trace-mcp 0.1.0
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/LICENSE +137 -0
- package/README.md +298 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +21188 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +656 -0
- package/dist/index.js +6797 -0
- package/dist/index.js.map +1 -0
- package/package.json +74 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/db/schema.ts","../src/logger.ts","../src/errors.ts","../src/db/store.ts","../src/plugin-api/registry.ts","../src/config.ts","../src/server.ts","../src/tools/project.ts","../src/tools/navigation.ts","../src/db/fts.ts","../src/utils/source-reader.ts","../src/utils/env-parser.ts","../src/scoring/hybrid.ts","../src/scoring/pagerank.ts","../src/ai/search.ts","../src/utils/token-counter.ts","../src/tools/components.ts","../src/tools/impact.ts","../src/tools/context.ts","../src/scoring/assembly.ts","../src/indexer/pipeline.ts","../src/plugin-api/executor.ts","../src/utils/hasher.ts","../src/utils/security.ts","../src/indexer/monorepo.ts","../src/indexer/resolvers/es-modules.ts","../src/ai/fallback.ts","../src/ai/ollama.ts","../src/ai/openai.ts","../src/ai/vector-store.ts","../src/ai/embedding-pipeline.ts","../src/ai/inference-cache.ts","../src/ai/cached-inference.ts","../src/ai/prompts.ts","../src/ai/summarization-pipeline.ts","../src/ai/reranker.ts","../src/ai/index.ts","../src/tools/ai-tools.ts","../src/scoring/structured-assembly.ts","../src/tools/middleware-chain.ts","../src/tools/module-graph.ts","../src/indexer/plugins/framework/nestjs/index.ts","../src/tools/di-tree.ts","../src/tools/rn-navigation.ts","../src/tools/screen-context.ts","../src/tools/flow.ts","../src/tools/model.ts","../src/tools/schema.ts","../src/tools/events.ts","../src/tools/references.ts","../src/tools/call-graph.ts","../src/tools/livewire.ts","../src/tools/nova.ts","../src/tools/tests.ts","../src/tools/introspect.ts","../src/indexer/plugins/language/php.ts","../src/indexer/plugins/language/php-helpers.ts","../src/indexer/plugins/language/typescript.ts","../src/indexer/plugins/language/ts-helpers.ts","../src/indexer/plugins/language/vue.ts","../src/indexer/plugins/language/vue-helpers.ts","../src/indexer/plugins/language/python.ts","../src/indexer/plugins/language/python-helpers.ts","../src/indexer/plugins/language/java.ts","../src/indexer/plugins/language/java-helpers.ts","../src/indexer/plugins/language/kotlin.ts","../src/indexer/plugins/language/ruby.ts","../src/indexer/plugins/language/ruby-helpers.ts","../src/indexer/plugins/language/go.ts","../src/indexer/plugins/language/go-helpers.ts","../src/indexer/plugins/framework/laravel/index.ts","../src/indexer/plugins/framework/laravel/routes.ts","../src/indexer/plugins/framework/laravel/eloquent.ts","../src/indexer/plugins/framework/laravel/migrations.ts","../src/indexer/plugins/framework/laravel/requests.ts","../src/indexer/plugins/framework/laravel/events.ts","../src/indexer/plugins/framework/laravel/livewire.ts","../src/indexer/plugins/framework/laravel/filament.ts","../src/indexer/plugins/framework/laravel/nova.ts","../src/indexer/plugins/framework/laravel/broadcasting.ts","../src/indexer/plugins/framework/laravel/laravel-data.ts","../src/indexer/plugins/framework/laravel/pennant.ts","../src/indexer/plugins/framework/laravel/middleware.ts","../src/indexer/plugins/framework/vue/index.ts","../src/indexer/plugins/framework/vue/resolver.ts","../src/indexer/plugins/framework/inertia/index.ts","../src/indexer/plugins/framework/nuxt/index.ts","../src/indexer/plugins/framework/blade/index.ts","../src/indexer/plugins/framework/nextjs/index.ts","../src/indexer/plugins/framework/express/index.ts","../src/indexer/plugins/framework/mongoose/index.ts","../src/indexer/plugins/framework/sequelize/index.ts","../src/indexer/plugins/framework/react-native/index.ts","../src/indexer/plugins/framework/prisma/index.ts","../src/indexer/plugins/framework/graphql/index.ts","../src/indexer/plugins/framework/typeorm/index.ts","../src/indexer/plugins/framework/drizzle/index.ts","../src/indexer/plugins/framework/drf/index.ts","../src/indexer/plugins/framework/pydantic/index.ts","../src/indexer/plugins/framework/celery/index.ts","../src/indexer/plugins/framework/fastapi/index.ts","../src/indexer/plugins/framework/flask/index.ts","../src/indexer/plugins/framework/sqlalchemy/index.ts","../src/indexer/plugins/framework/spring/index.ts","../src/indexer/plugins/framework/rails/index.ts","../src/indexer/plugins/framework/django/index.ts","../src/indexer/plugins/framework/django/models.ts","../src/indexer/plugins/framework/django/urls.ts","../src/indexer/plugins/framework/django/signals.ts","../src/indexer/plugins/framework/django/admin.ts","../src/indexer/plugins/framework/react/index.ts","../src/indexer/plugins/framework/trpc/index.ts","../src/indexer/plugins/framework/fastify/index.ts","../src/indexer/plugins/framework/hono/index.ts","../src/indexer/plugins/framework/socketio/index.ts","../src/indexer/plugins/framework/zustand/index.ts","../src/indexer/plugins/framework/n8n/index.ts","../src/indexer/plugins/framework/data-fetching/index.ts","../src/indexer/plugins/framework/zod/index.ts","../src/indexer/plugins/framework/testing/index.ts","../src/indexer/watcher.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { initializeDatabase } from './db/schema.js';\nimport { Store } from './db/store.js';\nimport { PluginRegistry } from './plugin-api/registry.js';\nimport { loadConfig } from './config.js';\nimport { createServer } from './server.js';\nimport { logger } from './logger.js';\nimport { PhpLanguagePlugin } from './indexer/plugins/language/php.js';\nimport { TypeScriptLanguagePlugin } from './indexer/plugins/language/typescript.js';\nimport { VueLanguagePlugin } from './indexer/plugins/language/vue.js';\nimport { PythonLanguagePlugin } from './indexer/plugins/language/python.js';\nimport { JavaLanguagePlugin } from './indexer/plugins/language/java.js';\nimport { KotlinLanguagePlugin } from './indexer/plugins/language/kotlin.js';\nimport { RubyLanguagePlugin } from './indexer/plugins/language/ruby.js';\nimport { GoLanguagePlugin } from './indexer/plugins/language/go.js';\nimport { LaravelPlugin } from './indexer/plugins/framework/laravel/index.js';\nimport { VueFrameworkPlugin } from './indexer/plugins/framework/vue/index.js';\nimport { InertiaPlugin } from './indexer/plugins/framework/inertia/index.js';\nimport { NuxtPlugin } from './indexer/plugins/framework/nuxt/index.js';\nimport { BladePlugin } from './indexer/plugins/framework/blade/index.js';\nimport { NestJSPlugin } from './indexer/plugins/framework/nestjs/index.js';\nimport { NextJSPlugin } from './indexer/plugins/framework/nextjs/index.js';\nimport { ExpressPlugin } from './indexer/plugins/framework/express/index.js';\nimport { MongoosePlugin } from './indexer/plugins/framework/mongoose/index.js';\nimport { SequelizePlugin } from './indexer/plugins/framework/sequelize/index.js';\nimport { ReactNativePlugin } from './indexer/plugins/framework/react-native/index.js';\nimport { PrismaPlugin, PrismaLanguagePlugin } from './indexer/plugins/framework/prisma/index.js';\nimport { GraphQLPlugin, GraphQLLanguagePlugin } from './indexer/plugins/framework/graphql/index.js';\nimport { TypeORMPlugin } from './indexer/plugins/framework/typeorm/index.js';\nimport { DrizzlePlugin } from './indexer/plugins/framework/drizzle/index.js';\nimport { DRFPlugin } from './indexer/plugins/framework/drf/index.js';\nimport { PydanticPlugin } from './indexer/plugins/framework/pydantic/index.js';\nimport { CeleryPlugin } from './indexer/plugins/framework/celery/index.js';\nimport { FastAPIPlugin } from './indexer/plugins/framework/fastapi/index.js';\nimport { FlaskPlugin } from './indexer/plugins/framework/flask/index.js';\nimport { SQLAlchemyPlugin } from './indexer/plugins/framework/sqlalchemy/index.js';\nimport { SpringPlugin } from './indexer/plugins/framework/spring/index.js';\nimport { RailsPlugin } from './indexer/plugins/framework/rails/index.js';\nimport { DjangoPlugin } from './indexer/plugins/framework/django/index.js';\nimport { ReactPlugin } from './indexer/plugins/framework/react/index.js';\nimport { TrpcPlugin } from './indexer/plugins/framework/trpc/index.js';\nimport { FastifyPlugin } from './indexer/plugins/framework/fastify/index.js';\nimport { HonoPlugin } from './indexer/plugins/framework/hono/index.js';\nimport { SocketIoPlugin } from './indexer/plugins/framework/socketio/index.js';\nimport { ZustandReduxPlugin } from './indexer/plugins/framework/zustand/index.js';\nimport { N8nPlugin } from './indexer/plugins/framework/n8n/index.js';\nimport { DataFetchingPlugin } from './indexer/plugins/framework/data-fetching/index.js';\nimport { ZodPlugin } from './indexer/plugins/framework/zod/index.js';\nimport { TestingPlugin } from './indexer/plugins/framework/testing/index.js';\nimport { IndexingPipeline } from './indexer/pipeline.js';\nimport { FileWatcher } from './indexer/watcher.js';\nimport { createAIProvider, BlobVectorStore, EmbeddingPipeline, InferenceCache, CachedInferenceService } from './ai/index.js';\nimport { SummarizationPipeline } from './ai/summarization-pipeline.js';\nimport http from 'node:http';\n\nfunction registerDefaultPlugins(registry: PluginRegistry): void {\n registry.registerLanguagePlugin(new PhpLanguagePlugin());\n registry.registerLanguagePlugin(new TypeScriptLanguagePlugin());\n registry.registerLanguagePlugin(new VueLanguagePlugin());\n registry.registerLanguagePlugin(new PythonLanguagePlugin());\n registry.registerLanguagePlugin(new JavaLanguagePlugin());\n registry.registerLanguagePlugin(new KotlinLanguagePlugin());\n registry.registerLanguagePlugin(new RubyLanguagePlugin());\n registry.registerLanguagePlugin(new GoLanguagePlugin());\n registry.registerLanguagePlugin(new PrismaLanguagePlugin());\n registry.registerLanguagePlugin(new GraphQLLanguagePlugin());\n registry.registerFrameworkPlugin(new LaravelPlugin());\n registry.registerFrameworkPlugin(new VueFrameworkPlugin());\n registry.registerFrameworkPlugin(new InertiaPlugin());\n registry.registerFrameworkPlugin(new NuxtPlugin());\n registry.registerFrameworkPlugin(new BladePlugin());\n registry.registerFrameworkPlugin(new NestJSPlugin());\n registry.registerFrameworkPlugin(new NextJSPlugin());\n registry.registerFrameworkPlugin(new ExpressPlugin());\n registry.registerFrameworkPlugin(new MongoosePlugin());\n registry.registerFrameworkPlugin(new SequelizePlugin());\n registry.registerFrameworkPlugin(new ReactNativePlugin());\n registry.registerFrameworkPlugin(new PrismaPlugin());\n registry.registerFrameworkPlugin(new GraphQLPlugin());\n registry.registerFrameworkPlugin(new TypeORMPlugin());\n registry.registerFrameworkPlugin(new DrizzlePlugin());\n registry.registerFrameworkPlugin(new DRFPlugin());\n registry.registerFrameworkPlugin(new PydanticPlugin());\n registry.registerFrameworkPlugin(new CeleryPlugin());\n registry.registerFrameworkPlugin(new FastAPIPlugin());\n registry.registerFrameworkPlugin(new FlaskPlugin());\n registry.registerFrameworkPlugin(new SQLAlchemyPlugin());\n registry.registerFrameworkPlugin(new DjangoPlugin());\n registry.registerFrameworkPlugin(new TrpcPlugin());\n registry.registerFrameworkPlugin(new FastifyPlugin());\n registry.registerFrameworkPlugin(new SocketIoPlugin());\n registry.registerFrameworkPlugin(new HonoPlugin());\n registry.registerFrameworkPlugin(new ZustandReduxPlugin());\n registry.registerFrameworkPlugin(new ReactPlugin());\n registry.registerFrameworkPlugin(new N8nPlugin());\n registry.registerFrameworkPlugin(new SpringPlugin());\n registry.registerFrameworkPlugin(new RailsPlugin());\n registry.registerFrameworkPlugin(new DataFetchingPlugin());\n registry.registerFrameworkPlugin(new ZodPlugin());\n registry.registerFrameworkPlugin(new TestingPlugin());\n}\n\nconst program = new Command();\n\nprogram\n .name('trace-mcp')\n .description('Framework-Aware Code Intelligence for Laravel/Vue/Inertia/Nuxt')\n .version('0.1.0');\n\nprogram\n .command('serve')\n .description('Start MCP server (stdio transport)')\n .action(async () => {\n const configResult = await loadConfig(process.cwd());\n if (configResult.isErr()) {\n logger.error({ error: configResult.error }, 'Failed to load config');\n process.exit(1);\n }\n const config = configResult.value;\n\n const dbPath = path.resolve(process.cwd(), config.db.path);\n const dbDir = path.dirname(dbPath);\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n\n const db = initializeDatabase(dbPath);\n const store = new Store(db);\n const registry = new PluginRegistry();\n registerDefaultPlugins(registry);\n\n const projectRoot = process.cwd();\n const pipeline = new IndexingPipeline(store, registry, config, projectRoot);\n const watcher = new FileWatcher();\n\n const aiProvider = createAIProvider(config);\n const vectorStore = config.ai?.enabled ? new BlobVectorStore(store.db) : null;\n const embeddingService = config.ai?.enabled ? aiProvider.embedding() : null;\n const embeddingPipeline = vectorStore && embeddingService\n ? new EmbeddingPipeline(store, embeddingService, vectorStore)\n : null;\n\n // Summarization pipeline (uses fast model + inference cache)\n const inferenceCache = config.ai?.enabled ? new InferenceCache(store.db) : null;\n const summarizationPipeline = config.ai?.enabled && config.ai.summarize_on_index !== false\n ? new SummarizationPipeline(\n store,\n new CachedInferenceService(aiProvider.fastInference(), inferenceCache!, config.ai.fast_model ?? 'fast'),\n projectRoot,\n {\n batchSize: config.ai.summarize_batch_size ?? 20,\n kinds: config.ai.summarize_kinds ?? ['class', 'function', 'method', 'interface', 'trait', 'enum', 'type'],\n },\n )\n : null;\n\n const runEmbeddings = () => {\n if (!embeddingPipeline) return;\n embeddingPipeline.indexUnembedded().catch((err) => {\n logger.error({ error: err }, 'Embedding indexing failed');\n });\n };\n\n const runSummarization = () => {\n if (!summarizationPipeline) return;\n summarizationPipeline.summarizeUnsummarized().catch((err) => {\n logger.error({ error: err }, 'Summarization failed');\n });\n };\n\n // Initial index runs in background so the server starts immediately\n // Summarization runs first (populates summaries), then embeddings (uses summaries for richer text)\n pipeline.indexAll().then(() => { runSummarization(); runEmbeddings(); }).catch((err) => {\n logger.error({ error: err }, 'Initial indexing failed');\n });\n\n await watcher.start(projectRoot, config, async (paths) => {\n await pipeline.indexFiles(paths);\n runSummarization();\n runEmbeddings();\n }, undefined, async (deleted) => {\n pipeline.deleteFiles(deleted);\n });\n\n const shutdown = async () => {\n await watcher.stop();\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n const server = createServer(store, registry, config, projectRoot);\n const transport = new StdioServerTransport();\n\n logger.info('Starting trace-mcp MCP server...');\n await server.connect(transport);\n });\n\nprogram\n .command('serve-http')\n .description('Start MCP server (HTTP/SSE transport)')\n .option('-p, --port <port>', 'Port to listen on', '3741')\n .option('--host <host>', 'Host to bind to', '127.0.0.1')\n .action(async (opts: { port: string; host: string }) => {\n const configResult = await loadConfig(process.cwd());\n if (configResult.isErr()) {\n logger.error({ error: configResult.error }, 'Failed to load config');\n process.exit(1);\n }\n const config = configResult.value;\n\n const dbPath = path.resolve(process.cwd(), config.db.path);\n const dbDir = path.dirname(dbPath);\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n\n const db = initializeDatabase(dbPath);\n const store = new Store(db);\n const registry = new PluginRegistry();\n registerDefaultPlugins(registry);\n\n const projectRoot = process.cwd();\n const pipeline = new IndexingPipeline(store, registry, config, projectRoot);\n const watcher = new FileWatcher();\n\n const aiProvider = createAIProvider(config);\n const vectorStore = config.ai?.enabled ? new BlobVectorStore(store.db) : null;\n const embeddingService = config.ai?.enabled ? aiProvider.embedding() : null;\n const embeddingPipeline = vectorStore && embeddingService\n ? new EmbeddingPipeline(store, embeddingService, vectorStore)\n : null;\n\n const inferenceCache2 = config.ai?.enabled ? new InferenceCache(store.db) : null;\n const summarizationPipeline2 = config.ai?.enabled && config.ai.summarize_on_index !== false\n ? new SummarizationPipeline(\n store,\n new CachedInferenceService(aiProvider.fastInference(), inferenceCache2!, config.ai.fast_model ?? 'fast'),\n projectRoot,\n {\n batchSize: config.ai.summarize_batch_size ?? 20,\n kinds: config.ai.summarize_kinds ?? ['class', 'function', 'method', 'interface', 'trait', 'enum', 'type'],\n },\n )\n : null;\n\n const runEmbeddings = () => {\n if (!embeddingPipeline) return;\n embeddingPipeline.indexUnembedded().catch((err) => {\n logger.error({ error: err }, 'Embedding indexing failed');\n });\n };\n\n const runSummarization2 = () => {\n if (!summarizationPipeline2) return;\n summarizationPipeline2.summarizeUnsummarized().catch((err) => {\n logger.error({ error: err }, 'Summarization failed');\n });\n };\n\n pipeline.indexAll().then(() => { runSummarization2(); runEmbeddings(); }).catch((err) => {\n logger.error({ error: err }, 'Initial indexing failed');\n });\n\n await watcher.start(projectRoot, config, async (paths) => {\n await pipeline.indexFiles(paths);\n runSummarization2();\n runEmbeddings();\n }, undefined, async (deleted) => {\n pipeline.deleteFiles(deleted);\n });\n\n const port = parseInt(opts.port, 10);\n const host = opts.host;\n\n // Simple per-IP rate limiter (token bucket: 60 requests/minute per IP)\n const RATE_WINDOW_MS = 60_000;\n const RATE_LIMIT = 60;\n const rateBuckets = new Map<string, { count: number; resetAt: number }>();\n\n function isRateLimited(ip: string): boolean {\n const now = Date.now();\n const bucket = rateBuckets.get(ip);\n if (!bucket || now > bucket.resetAt) {\n rateBuckets.set(ip, { count: 1, resetAt: now + RATE_WINDOW_MS });\n return false;\n }\n bucket.count++;\n return bucket.count > RATE_LIMIT;\n }\n\n // Periodically evict expired rate-limit buckets to prevent memory leak\n const rateBucketCleanup = setInterval(() => {\n const now = Date.now();\n for (const [ip, bucket] of rateBuckets) {\n if (now > bucket.resetAt) rateBuckets.delete(ip);\n }\n }, RATE_WINDOW_MS);\n rateBucketCleanup.unref(); // Don't block process exit\n\n // Max request body size (5 MB)\n const MAX_BODY_SIZE = 5 * 1024 * 1024;\n\n // Stateless HTTP transport: each request gets its own transport instance\n const httpServer = http.createServer(async (req, res) => {\n const clientIp = req.socket.remoteAddress ?? 'unknown';\n\n if (isRateLimited(clientIp)) {\n res.writeHead(429, { 'Content-Type': 'application/json', 'Retry-After': '60' });\n res.end(JSON.stringify({ error: 'Too many requests' }));\n return;\n }\n\n // Enforce max body size\n let bodySize = 0;\n req.on('data', (chunk: Buffer) => {\n bodySize += chunk.length;\n if (bodySize > MAX_BODY_SIZE) {\n res.writeHead(413, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Request body too large' }));\n req.destroy();\n }\n });\n\n if (req.method === 'POST' && req.url === '/mcp') {\n const server = createServer(store, registry, config, projectRoot);\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined, // stateless\n });\n res.on('close', () => {\n transport.close().catch(() => {});\n server.close().catch(() => {});\n });\n await server.connect(transport);\n await transport.handleRequest(req, res);\n return;\n }\n\n if (req.method === 'GET' && req.url === '/health') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'ok', transport: 'http' }));\n return;\n }\n\n res.writeHead(404);\n res.end();\n });\n\n const shutdown = async () => {\n await watcher.stop();\n httpServer.close(() => process.exit(0));\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n httpServer.listen(port, host, () => {\n logger.info({ host, port, endpoint: `http://${host}:${port}/mcp` }, 'trace-mcp HTTP server started');\n });\n });\n\nprogram\n .command('index')\n .description('Index a project directory')\n .argument('<dir>', 'Directory to index')\n .option('-f, --force', 'Force reindex all files')\n .action(async (dir: string, opts: { force?: boolean }) => {\n const resolvedDir = path.resolve(dir);\n if (!fs.existsSync(resolvedDir)) {\n logger.error({ dir: resolvedDir }, 'Directory does not exist');\n process.exit(1);\n }\n\n const configResult = await loadConfig(resolvedDir);\n if (configResult.isErr()) {\n logger.error({ error: configResult.error }, 'Failed to load config');\n process.exit(1);\n }\n const config = configResult.value;\n\n const dbPath = path.resolve(resolvedDir, config.db.path);\n const dbDir = path.dirname(dbPath);\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n\n const db = initializeDatabase(dbPath);\n const store = new Store(db);\n const registry = new PluginRegistry();\n registerDefaultPlugins(registry);\n\n logger.info({ dir: resolvedDir, dbPath, force: opts.force ?? false }, 'Indexing started');\n\n const pipeline = new IndexingPipeline(store, registry, config, resolvedDir);\n const result = await pipeline.indexAll(opts.force ?? false);\n logger.info(result, 'Indexing completed');\n\n db.close();\n });\n\nprogram.parse();\n","import Database from 'better-sqlite3';\nimport { logger } from '../logger.js';\n\nconst SCHEMA_VERSION = 5;\n\nconst DDL = `\n-- ============================================================\n-- UNIFIED ADDRESS SPACE\n-- ============================================================\n\nCREATE TABLE IF NOT EXISTS node_types (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL UNIQUE\n);\n\nCREATE TABLE IF NOT EXISTS edge_types (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n category TEXT NOT NULL,\n directed INTEGER NOT NULL DEFAULT 1,\n description TEXT\n);\n\nCREATE TABLE IF NOT EXISTS nodes (\n id INTEGER PRIMARY KEY,\n node_type TEXT NOT NULL REFERENCES node_types(name),\n ref_id INTEGER NOT NULL,\n UNIQUE(node_type, ref_id)\n);\n\n-- ============================================================\n-- CONCRETE ENTITY TABLES\n-- ============================================================\n\nCREATE TABLE IF NOT EXISTS files (\n id INTEGER PRIMARY KEY,\n path TEXT NOT NULL UNIQUE,\n language TEXT,\n framework_role TEXT,\n status TEXT DEFAULT 'ok',\n content_hash TEXT,\n byte_length INTEGER,\n indexed_at TEXT NOT NULL,\n metadata TEXT,\n workspace TEXT\n);\n\nCREATE TABLE IF NOT EXISTS symbols (\n id INTEGER PRIMARY KEY,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n symbol_id TEXT NOT NULL UNIQUE,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n fqn TEXT,\n parent_id INTEGER REFERENCES symbols(id),\n signature TEXT,\n summary TEXT,\n byte_start INTEGER NOT NULL,\n byte_end INTEGER NOT NULL,\n line_start INTEGER,\n line_end INTEGER,\n metadata TEXT\n);\n\nCREATE TABLE IF NOT EXISTS routes (\n id INTEGER PRIMARY KEY,\n method TEXT NOT NULL,\n uri TEXT NOT NULL,\n name TEXT,\n handler TEXT,\n controller_symbol_id INTEGER REFERENCES symbols(id),\n middleware TEXT,\n metadata TEXT,\n file_id INTEGER REFERENCES files(id),\n line INTEGER\n);\n\nCREATE TABLE IF NOT EXISTS components (\n id INTEGER PRIMARY KEY,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n props TEXT,\n emits TEXT,\n slots TEXT,\n composables TEXT,\n framework TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS migrations (\n id INTEGER PRIMARY KEY,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n table_name TEXT NOT NULL,\n operation TEXT NOT NULL,\n columns TEXT,\n indices TEXT,\n timestamp TEXT\n);\n\n-- ============================================================\n-- ORM MODELS (Mongoose + Sequelize)\n-- ============================================================\n\nCREATE TABLE IF NOT EXISTS orm_models (\n id INTEGER PRIMARY KEY,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n orm TEXT NOT NULL,\n collection_or_table TEXT,\n fields TEXT,\n options TEXT,\n metadata TEXT\n);\n\nCREATE TABLE IF NOT EXISTS orm_associations (\n id INTEGER PRIMARY KEY,\n source_model_id INTEGER NOT NULL REFERENCES orm_models(id) ON DELETE CASCADE,\n target_model_id INTEGER REFERENCES orm_models(id),\n target_model_name TEXT,\n kind TEXT NOT NULL,\n options TEXT,\n file_id INTEGER REFERENCES files(id),\n line INTEGER\n);\n\n-- ============================================================\n-- REACT NATIVE SCREENS\n-- ============================================================\n\nCREATE TABLE IF NOT EXISTS rn_screens (\n id INTEGER PRIMARY KEY,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n component_path TEXT,\n navigator_type TEXT,\n options TEXT,\n deep_link TEXT,\n metadata TEXT\n);\n\n-- ============================================================\n-- ENV VARS (keys only — values are never stored)\n-- ============================================================\n\nCREATE TABLE IF NOT EXISTS env_vars (\n id INTEGER PRIMARY KEY,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n key TEXT NOT NULL,\n value_type TEXT NOT NULL,\n value_format TEXT,\n comment TEXT,\n quoted INTEGER NOT NULL DEFAULT 0,\n line INTEGER\n);\n\nCREATE INDEX IF NOT EXISTS idx_env_vars_file ON env_vars(file_id);\nCREATE INDEX IF NOT EXISTS idx_env_vars_key ON env_vars(key);\n\n-- ============================================================\n-- UNIFIED EDGES\n-- ============================================================\n\nCREATE TABLE IF NOT EXISTS edges (\n id INTEGER PRIMARY KEY,\n source_node_id INTEGER NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,\n target_node_id INTEGER NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,\n edge_type_id INTEGER NOT NULL REFERENCES edge_types(id),\n resolved INTEGER NOT NULL DEFAULT 1,\n metadata TEXT,\n is_cross_ws INTEGER NOT NULL DEFAULT 0,\n UNIQUE(source_node_id, target_node_id, edge_type_id)\n);\n\nCREATE INDEX IF NOT EXISTS idx_edges_source ON edges(source_node_id);\nCREATE INDEX IF NOT EXISTS idx_edges_target ON edges(target_node_id);\nCREATE INDEX IF NOT EXISTS idx_edges_type ON edges(edge_type_id);\nCREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_id);\nCREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);\nCREATE INDEX IF NOT EXISTS idx_symbols_fqn ON symbols(fqn);\nCREATE INDEX IF NOT EXISTS idx_nodes_type ON nodes(node_type);\n\n-- ============================================================\n-- FTS5 FULL-TEXT SEARCH\n-- ============================================================\n\nCREATE VIRTUAL TABLE IF NOT EXISTS symbols_fts USING fts5(\n name, fqn, signature, summary,\n content=symbols, content_rowid=id\n);\n\n-- ============================================================\n-- FTS5 TRIGGERS (keep in sync)\n-- ============================================================\n\nCREATE TRIGGER IF NOT EXISTS symbols_ai AFTER INSERT ON symbols BEGIN\n INSERT INTO symbols_fts(rowid, name, fqn, signature, summary)\n VALUES (new.id, new.name, new.fqn, new.signature, new.summary);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS symbols_ad AFTER DELETE ON symbols BEGIN\n INSERT INTO symbols_fts(symbols_fts, rowid, name, fqn, signature, summary)\n VALUES ('delete', old.id, old.name, old.fqn, old.signature, old.summary);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS symbols_au AFTER UPDATE ON symbols BEGIN\n INSERT INTO symbols_fts(symbols_fts, rowid, name, fqn, signature, summary)\n VALUES ('delete', old.id, old.name, old.fqn, old.signature, old.summary);\n INSERT INTO symbols_fts(rowid, name, fqn, signature, summary)\n VALUES (new.id, new.name, new.fqn, new.signature, new.summary);\nEND;\n\n-- ============================================================\n-- AI EMBEDDINGS (optional, for Phase 7)\n-- ============================================================\n\nCREATE TABLE IF NOT EXISTS symbol_embeddings (\n symbol_id INTEGER PRIMARY KEY REFERENCES symbols(id) ON DELETE CASCADE,\n embedding BLOB NOT NULL\n);\n\n-- ============================================================\n-- AI INFERENCE CACHE (optional, for cached summarization)\n-- ============================================================\n\nCREATE TABLE IF NOT EXISTS inference_cache (\n cache_key TEXT PRIMARY KEY,\n model TEXT NOT NULL,\n prompt_hash TEXT NOT NULL,\n response TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n ttl_days INTEGER DEFAULT 90\n);\nCREATE INDEX IF NOT EXISTS idx_inference_cache_model ON inference_cache(model);\n\n-- ============================================================\n-- SCHEMA VERSION\n-- ============================================================\n\nCREATE TABLE IF NOT EXISTS schema_meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n);\n\n-- Applied migration log (one row per migration that has been run)\nCREATE TABLE IF NOT EXISTS schema_migrations (\n version INTEGER PRIMARY KEY,\n applied_at TEXT NOT NULL\n);\n`;\n\nconst SEED_NODE_TYPES = ['symbol', 'file', 'route', 'component', 'migration', 'orm_model', 'rn_screen'];\n\nconst SEED_EDGE_TYPES = [\n // Core edges (added in v2 migration, must also be in seed for fresh DBs)\n { name: 'calls', category: 'core', description: 'Direct function/method call' },\n { name: 'references', category: 'core', description: 'Symbol reference (read/write)' },\n { name: 'unresolved', category: 'core', description: 'Phantom edge for unresolved targets' },\n { name: 'test_covers', category: 'core', description: 'Test file covers a symbol or file' },\n { name: 'esm_imports', category: 'core', description: 'ESM import (file→file)' },\n { name: 'graphql_resolves', category: 'graphql', description: 'Resolver implements a GraphQL field' },\n { name: 'graphql_references_type', category: 'graphql', description: 'Resolver/field references a GraphQL type' },\n // PHP language edges\n { name: 'imports', category: 'php', description: 'PHP use/import statement' },\n { name: 'extends', category: 'php', description: 'Class/interface extends' },\n { name: 'implements', category: 'php', description: 'Class implements interface' },\n { name: 'uses_trait', category: 'php', description: 'Class uses trait' },\n // TypeScript language edges\n { name: 'ts_extends', category: 'typescript', description: 'TypeScript class/interface extends' },\n { name: 'ts_implements', category: 'typescript', description: 'TypeScript class implements interface' },\n // Laravel framework edges\n { name: 'routes_to', category: 'laravel', description: 'Route -> Controller' },\n { name: 'has_many', category: 'laravel', description: 'Eloquent hasMany' },\n { name: 'belongs_to', category: 'laravel', description: 'Eloquent belongsTo' },\n { name: 'belongs_to_many', category: 'laravel', description: 'Eloquent belongsToMany' },\n { name: 'has_one', category: 'laravel', description: 'Eloquent hasOne' },\n { name: 'morphs_to', category: 'laravel', description: 'Eloquent morphTo' },\n { name: 'validates_with', category: 'laravel', description: 'Controller -> FormRequest' },\n { name: 'dispatches', category: 'laravel', description: 'Dispatches event/job' },\n { name: 'listens_to', category: 'laravel', description: 'Listener -> Event' },\n { name: 'middleware_guards', category: 'laravel', description: 'Route -> Middleware' },\n { name: 'migrates', category: 'laravel', description: 'Migration -> table' },\n // Vue framework edges\n { name: 'renders_component', category: 'vue', description: 'Parent component renders child in template' },\n { name: 'uses_composable', category: 'vue', description: 'Component calls a composable function' },\n { name: 'provides_slot', category: 'vue', description: 'Component provides a named slot' },\n // Inertia edges\n { name: 'inertia_renders', category: 'inertia', description: 'Controller renders Vue page via Inertia' },\n { name: 'passes_props', category: 'inertia', description: 'Controller passes props to Vue page' },\n // Nuxt edges\n { name: 'nuxt_auto_imports', category: 'nuxt', description: 'Auto-imported composable' },\n { name: 'api_calls', category: 'nuxt', description: 'fetch/useFetch API call' },\n { name: 'nuxt_shared_import', category: 'nuxt', description: 'Auto-imported shared utility or type' },\n // Blade edges\n { name: 'blade_extends', category: 'blade', description: '@extends directive' },\n { name: 'blade_includes', category: 'blade', description: '@include directive' },\n { name: 'blade_component', category: 'blade', description: '<x-component> or @component' },\n // Nova edges\n { name: 'nova_resource_for', category: 'nova', description: 'Nova Resource → Eloquent Model' },\n { name: 'nova_field_relationship', category: 'nova', description: 'Nova Resource → related Nova Resource via field' },\n { name: 'nova_action_on', category: 'nova', description: 'Action → Resource' },\n { name: 'nova_filter_on', category: 'nova', description: 'Filter → Resource' },\n { name: 'nova_lens_on', category: 'nova', description: 'Lens → Resource' },\n { name: 'nova_metric_queries', category: 'nova', description: 'Metric → Eloquent Model' },\n // Filament edges\n { name: 'filament_resource_for', category: 'filament', description: 'Resource → Eloquent Model' },\n { name: 'filament_relation_manager', category: 'filament', description: 'Resource → RelationManager' },\n { name: 'filament_form_relationship', category: 'filament', description: 'Form field →relationship() → Model' },\n { name: 'filament_page_for', category: 'filament', description: 'Page registered on Resource' },\n { name: 'filament_panel_registers', category: 'filament', description: 'PanelProvider → Resource/Page/Widget' },\n { name: 'filament_widget_queries', category: 'filament', description: 'Widget → Eloquent Model' },\n // Livewire edges\n { name: 'livewire_renders', category: 'livewire', description: 'Component class → Blade view' },\n { name: 'livewire_dispatches', category: 'livewire', description: 'Component dispatches event' },\n { name: 'livewire_listens', category: 'livewire', description: 'Component listens for event' },\n { name: 'livewire_child_of', category: 'livewire', description: 'Blade <livewire:child/> → Component' },\n { name: 'livewire_uses_model', category: 'livewire', description: 'Component → Eloquent Model' },\n { name: 'livewire_form', category: 'livewire', description: 'Component → Form class (v3)' },\n { name: 'livewire_action', category: 'livewire', description: 'wire:click → Component method' },\n // NestJS edges\n { name: 'nest_module_imports', category: 'nestjs', description: 'Module imports another module' },\n { name: 'nest_provides', category: 'nestjs', description: 'Module provides a service' },\n { name: 'nest_injects', category: 'nestjs', description: 'Constructor dependency injection' },\n { name: 'nest_guards', category: 'nestjs', description: 'UseGuards on controller/method' },\n { name: 'nest_pipes', category: 'nestjs', description: 'UsePipes on controller/method' },\n { name: 'nest_interceptors', category: 'nestjs', description: 'UseInterceptors on controller/method' },\n { name: 'nest_gateway_event', category: 'nestjs', description: 'WebSocket gateway @SubscribeMessage handler' },\n { name: 'nest_message_pattern', category: 'nestjs', description: 'Microservice @MessagePattern handler' },\n { name: 'nest_event_pattern', category: 'nestjs', description: 'Microservice @EventPattern handler' },\n // Next.js edges\n { name: 'next_renders_page', category: 'nextjs', description: 'Layout renders page' },\n { name: 'next_server_action', category: 'nextjs', description: 'Server action reference' },\n { name: 'next_middleware', category: 'nextjs', description: 'Middleware applies to routes' },\n { name: 'next_parallel_slot', category: 'nextjs', description: 'Parallel route slot' },\n { name: 'next_intercepting', category: 'nextjs', description: 'Intercepting route' },\n { name: 'next_data_fetching', category: 'nextjs', description: 'Pages Router data fetching function' },\n { name: 'next_template', category: 'nextjs', description: 'Template component for route segment' },\n // Express edges\n { name: 'express_route', category: 'express', description: 'Express route handler' },\n { name: 'express_middleware', category: 'express', description: 'Express middleware' },\n { name: 'express_mounts', category: 'express', description: 'Router mount via app.use' },\n { name: 'express_error_handler', category: 'express', description: '4-arg error handling middleware' },\n { name: 'express_param_handler', category: 'express', description: 'app.param() route parameter handler' },\n // Mongoose edges\n { name: 'mongoose_references', category: 'mongoose', description: 'ObjectId ref to another model' },\n { name: 'mongoose_has_virtual', category: 'mongoose', description: 'Schema virtual field' },\n { name: 'mongoose_has_middleware', category: 'mongoose', description: 'Schema pre/post hook' },\n { name: 'mongoose_has_method', category: 'mongoose', description: 'Schema instance method' },\n { name: 'mongoose_has_static', category: 'mongoose', description: 'Schema static method' },\n { name: 'mongoose_discriminates', category: 'mongoose', description: 'Model discriminator' },\n { name: 'mongoose_has_index', category: 'mongoose', description: 'Schema index' },\n { name: 'mongoose_uses_plugin', category: 'mongoose', description: 'Schema plugin' },\n // Sequelize edges\n { name: 'sequelize_has_many', category: 'sequelize', description: 'Sequelize hasMany association' },\n { name: 'sequelize_belongs_to', category: 'sequelize', description: 'Sequelize belongsTo association' },\n { name: 'sequelize_belongs_to_many', category: 'sequelize', description: 'Sequelize belongsToMany association' },\n { name: 'sequelize_has_one', category: 'sequelize', description: 'Sequelize hasOne association' },\n { name: 'sequelize_has_hook', category: 'sequelize', description: 'Sequelize lifecycle hook' },\n { name: 'sequelize_has_scope', category: 'sequelize', description: 'Sequelize named scope' },\n { name: 'sequelize_migrates', category: 'sequelize', description: 'Migration changes table schema' },\n // React Native edges\n { name: 'rn_navigates_to', category: 'react-native', description: 'navigation.navigate() to screen' },\n { name: 'rn_screen_in_navigator', category: 'react-native', description: 'Screen registered in navigator' },\n { name: 'rn_uses_native_module', category: 'react-native', description: 'Uses NativeModules/TurboModuleRegistry' },\n { name: 'rn_platform_specific', category: 'react-native', description: 'Platform-specific file variant' },\n { name: 'rn_deep_links_to', category: 'react-native', description: 'Deep link maps to screen' },\n { name: 'expo_route', category: 'expo-router', description: 'Expo Router file-based route' },\n { name: 'expo_layout', category: 'expo-router', description: 'Expo Router layout file' },\n // Python language edges\n { name: 'py_imports', category: 'python', description: 'Python import statement' },\n { name: 'py_reexports', category: 'python', description: '__init__.py re-export' },\n { name: 'py_param_type', category: 'python', description: 'Function parameter type annotation' },\n { name: 'py_return_type', category: 'python', description: 'Function return type annotation' },\n { name: 'py_inherits', category: 'python', description: 'Class inheritance' },\n { name: 'py_uses_decorator', category: 'python', description: 'Function/class uses decorator' },\n // Django edges\n { name: 'django_url_routes_to', category: 'django', description: 'URL pattern routes to view' },\n { name: 'django_includes_urls', category: 'django', description: 'include() sub-URL config' },\n { name: 'django_view_uses_model', category: 'django', description: 'View references model' },\n { name: 'django_view_template', category: 'django', description: 'View renders template' },\n { name: 'django_signal_receiver', category: 'django', description: '@receiver signal handler' },\n { name: 'django_admin_registers', category: 'django', description: 'Admin registers model' },\n { name: 'django_form_meta_model', category: 'django', description: 'ModelForm Meta.model' },\n { name: 'django_migrates', category: 'django', description: 'Django migration operation' },\n // FastAPI edges\n { name: 'fastapi_route', category: 'fastapi', description: 'FastAPI route decorator' },\n { name: 'fastapi_depends', category: 'fastapi', description: 'Depends() dependency injection' },\n { name: 'fastapi_request_model', category: 'fastapi', description: 'Request body Pydantic model' },\n { name: 'fastapi_response_model', category: 'fastapi', description: 'response_model parameter' },\n { name: 'fastapi_router_mounts', category: 'fastapi', description: 'include_router() mount' },\n // Flask edges\n { name: 'flask_route', category: 'flask', description: 'Flask @app.route decorator' },\n { name: 'flask_blueprint_mounts', category: 'flask', description: 'register_blueprint() mount' },\n { name: 'flask_before_request', category: 'flask', description: '@before_request hook' },\n { name: 'flask_error_handler', category: 'flask', description: '@errorhandler hook' },\n // SQLAlchemy edges\n { name: 'sqla_relationship', category: 'sqlalchemy', description: 'SQLAlchemy relationship()' },\n { name: 'sqla_fk', category: 'sqlalchemy', description: 'ForeignKey reference' },\n { name: 'sqla_migrates', category: 'sqlalchemy', description: 'Alembic migration operation' },\n // DRF edges\n { name: 'drf_serializer_model', category: 'drf', description: 'ModelSerializer Meta.model' },\n { name: 'drf_viewset_serializer', category: 'drf', description: 'ViewSet serializer_class' },\n { name: 'drf_router_registers', category: 'drf', description: 'router.register() ViewSet' },\n { name: 'drf_permission_guards', category: 'drf', description: 'permission_classes on ViewSet' },\n // Pydantic edges\n { name: 'pydantic_field_type', category: 'pydantic', description: 'BaseModel field type reference' },\n { name: 'pydantic_from_orm', category: 'pydantic', description: 'Model with from_attributes → ORM model' },\n // Celery edges\n { name: 'celery_task_registered', category: 'celery', description: '@app.task / @shared_task registration' },\n { name: 'celery_beat_schedule', category: 'celery', description: 'Beat schedule task entry' },\n { name: 'celery_dispatches', category: 'celery', description: '.delay() / .apply_async() dispatch' },\n // Pennant (feature flags) edges\n { name: 'feature_defined_in', category: 'pennant', description: 'Feature flag defined via Feature::define()' },\n { name: 'feature_checked_by', category: 'pennant', description: 'Feature flag checked in PHP/Blade' },\n { name: 'feature_gates_route', category: 'pennant', description: 'Route protected by features middleware' },\n // Broadcasting / Reverb edges\n { name: 'broadcasts_on', category: 'broadcasting', description: 'Event broadcasts on a channel' },\n { name: 'channel_authorized_by', category: 'broadcasting', description: 'Channel authorization callback or class' },\n { name: 'broadcast_as', category: 'broadcasting', description: 'Event broadcast name override' },\n // laravel-data edges\n { name: 'data_wraps', category: 'laravel-data', description: 'Data class wraps an Eloquent model' },\n { name: 'data_property_type', category: 'laravel-data', description: 'Data class property references another Data class' },\n { name: 'data_collection', category: 'laravel-data', description: 'DataCollection<T> references a Data class' },\n // State management (Zustand / Redux Toolkit)\n { name: 'zustand_store', category: 'state-management', description: 'Zustand store definition' },\n { name: 'redux_slice', category: 'state-management', description: 'Redux Toolkit slice definition' },\n { name: 'dispatches_action', category: 'state-management', description: 'Component dispatches a Redux/Zustand action' },\n { name: 'selects_state', category: 'state-management', description: 'Component selects state from store' },\n // tRPC edges\n { name: 'trpc_procedure', category: 'trpc', description: 'Procedure defined in router' },\n // Fastify edges\n { name: 'fastify_route', category: 'fastify', description: 'Route handler' },\n { name: 'fastify_hook', category: 'fastify', description: 'Lifecycle hook' },\n { name: 'fastify_plugin', category: 'fastify', description: 'Plugin registration' },\n // Socket.io edges\n { name: 'socketio_event', category: 'socketio', description: 'Event listener/emitter' },\n { name: 'socketio_namespace', category: 'socketio', description: 'Namespace definition' },\n // React (standalone) edges\n { name: 'react_renders', category: 'react', description: 'Parent component renders child via JSX' },\n { name: 'react_context_provides', category: 'react', description: 'Context.Provider usage' },\n { name: 'react_context_consumes', category: 'react', description: 'useContext() or use() call' },\n { name: 'react_lazy_loads', category: 'react', description: 'React.lazy(() => import(\"./X\"))' },\n { name: 'react_custom_hook_uses', category: 'react', description: 'Component calls a custom hook' },\n { name: 'react_use_client', category: 'react', description: \"'use client' directive (React 19)\" },\n { name: 'react_use_server', category: 'react', description: \"'use server' directive (React 19)\" },\n // Hono edges\n { name: 'hono_route', category: 'hono', description: 'Hono route handler' },\n { name: 'hono_middleware', category: 'hono', description: 'Hono middleware usage' },\n // Data fetching (React Query / SWR) edges\n { name: 'fetches_endpoint', category: 'data-fetching', description: 'useQuery/useSWR call referencing an API endpoint' },\n // Zod edges\n { name: 'zod_schema', category: 'zod', description: 'Zod schema definition' },\n // Testing framework edges\n { name: 'test_covers_route', category: 'testing', description: 'Test file visits/requests an API route' },\n { name: 'test_covers_component', category: 'testing', description: 'Test file mounts/renders a component' },\n { name: 'test_imports_module', category: 'testing', description: 'Test file imports the module under test' },\n // Workspace edges\n { name: 'workspace_import', category: 'workspace', description: 'Cross-workspace import' },\n { name: 'api_call', category: 'workspace', description: 'Cross-workspace API call' },\n { name: 'type_import', category: 'workspace', description: 'Cross-workspace type import' },\n];\n\n/**\n * Incremental migrations, keyed by target schema version.\n * Each entry runs exactly once, in version order.\n * Add new entries here whenever the schema changes.\n */\nconst MIGRATIONS: Record<number, (db: Database.Database) => void> = {\n 2: (db) => {\n // v2: add schema_migrations table (already in DDL via CREATE TABLE IF NOT EXISTS,\n // but mark it as applied for all future installs)\n db.exec(`\n INSERT OR IGNORE INTO edge_types (name, category, directed, description)\n VALUES\n ('calls', 'core', 1, 'Direct function/method call'),\n ('references', 'core', 1, 'Symbol reference (read/write)'),\n ('test_covers', 'core', 1, 'Test file covers a symbol or file'),\n ('graphql_resolves', 'graphql', 1, 'Resolver implements a GraphQL field'),\n ('graphql_references_type', 'graphql', 1, 'Resolver/field references a GraphQL type');\n `);\n },\n 3: (db) => {\n // v3: TypeScript heritage edges — enables find_references for extends/implements\n db.exec(`\n INSERT OR IGNORE INTO edge_types (name, category, directed, description)\n VALUES\n ('ts_extends', 'typescript', 1, 'TypeScript class/interface extends'),\n ('ts_implements', 'typescript', 1, 'TypeScript class implements interface');\n `);\n },\n 4: (db) => {\n // v4: AI inference cache for summarization pipeline\n db.exec(`\n CREATE TABLE IF NOT EXISTS inference_cache (\n cache_key TEXT PRIMARY KEY,\n model TEXT NOT NULL,\n prompt_hash TEXT NOT NULL,\n response TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n ttl_days INTEGER DEFAULT 90\n );\n CREATE INDEX IF NOT EXISTS idx_inference_cache_model ON inference_cache(model);\n `);\n },\n 5: (db) => {\n // v5: env_vars table — stores .env keys with type metadata, never stores values\n db.exec(`\n CREATE TABLE IF NOT EXISTS env_vars (\n id INTEGER PRIMARY KEY,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n key TEXT NOT NULL,\n value_type TEXT NOT NULL,\n value_format TEXT,\n comment TEXT,\n quoted INTEGER NOT NULL DEFAULT 0,\n line INTEGER\n );\n CREATE INDEX IF NOT EXISTS idx_env_vars_file ON env_vars(file_id);\n CREATE INDEX IF NOT EXISTS idx_env_vars_key ON env_vars(key);\n `);\n },\n};\n\nfunction runMigrations(db: Database.Database, fromVersion: number): void {\n const versions = Object.keys(MIGRATIONS)\n .map(Number)\n .filter((v) => v > fromVersion)\n .sort((a, b) => a - b);\n\n if (versions.length === 0) return;\n\n const insertMigration = db.prepare(\n \"INSERT OR IGNORE INTO schema_migrations (version, applied_at) VALUES (?, ?)\",\n );\n const updateVersion = db.prepare(\n \"INSERT OR REPLACE INTO schema_meta (key, value) VALUES ('schema_version', ?)\",\n );\n\n for (const version of versions) {\n logger.info({ version }, 'Running schema migration');\n db.transaction(() => {\n MIGRATIONS[version](db);\n insertMigration.run(version, new Date().toISOString());\n updateVersion.run(String(version));\n })();\n logger.info({ version }, 'Schema migration applied');\n }\n}\n\nexport function initializeDatabase(dbPath: string): Database.Database {\n const db = new Database(dbPath);\n\n // WAL mode for concurrent reads\n db.pragma('journal_mode = WAL');\n db.pragma('foreign_keys = ON');\n db.pragma('busy_timeout = 5000');\n\n db.exec(DDL);\n\n // Check schema version and run any pending migrations\n const versionRow = db.prepare(\"SELECT value FROM schema_meta WHERE key = 'schema_version'\").get() as { value: string } | undefined;\n\n if (!versionRow) {\n // Fresh database — seed and stamp with current version\n seedDatabase(db);\n db.prepare(\"INSERT INTO schema_meta (key, value) VALUES ('schema_version', ?)\").run(String(SCHEMA_VERSION));\n // Mark all migrations as already applied (they're baked into seed/DDL)\n const insertMigration = db.prepare(\n \"INSERT OR IGNORE INTO schema_migrations (version, applied_at) VALUES (?, ?)\",\n );\n const now = new Date().toISOString();\n for (const v of Object.keys(MIGRATIONS).map(Number)) {\n insertMigration.run(v, now);\n }\n } else {\n const currentVersion = parseInt(versionRow.value, 10);\n if (currentVersion < SCHEMA_VERSION) {\n logger.info({ from: currentVersion, to: SCHEMA_VERSION }, 'Schema upgrade required');\n runMigrations(db, currentVersion);\n }\n }\n\n logger.debug({ dbPath, schemaVersion: SCHEMA_VERSION }, 'Database initialized');\n return db;\n}\n\nfunction seedDatabase(db: Database.Database): void {\n const insertNodeType = db.prepare('INSERT OR IGNORE INTO node_types (name) VALUES (?)');\n for (const name of SEED_NODE_TYPES) {\n insertNodeType.run(name);\n }\n\n const insertEdgeType = db.prepare(\n 'INSERT OR IGNORE INTO edge_types (name, category, directed, description) VALUES (?, ?, 1, ?)',\n );\n for (const et of SEED_EDGE_TYPES) {\n insertEdgeType.run(et.name, et.category, et.description);\n }\n}\n\nexport function getTableNames(db: Database.Database): string[] {\n const rows = db.prepare(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name\",\n ).all() as { name: string }[];\n return rows.map((r) => r.name);\n}\n\nexport function getVirtualTableNames(db: Database.Database): string[] {\n const rows = db.prepare(\n \"SELECT name FROM sqlite_master WHERE type='table' AND sql LIKE '%VIRTUAL%' ORDER BY name\",\n ).all() as { name: string }[];\n return rows.map((r) => r.name);\n}\n","import pino from 'pino';\n\nconst level = process.env.TRACE_MCP_LOG_LEVEL ?? 'info';\n\nexport const logger = pino({\n name: 'trace-mcp',\n level,\n transport:\n process.env.NODE_ENV !== 'production'\n ? { target: 'pino/file', options: { destination: 2 } } // stderr\n : undefined,\n});\n","import { err, ok, Result } from 'neverthrow';\n\nexport type TraceMcpError =\n | { code: 'PARSE_ERROR'; file: string; partial: boolean; message: string }\n | { code: 'NOT_FOUND'; id: string; candidates?: string[] }\n | { code: 'RESOLUTION_FAILED'; path: string; message: string }\n | { code: 'TIMEOUT'; operation: string; ms: number }\n | { code: 'SECURITY_VIOLATION'; detail: string }\n | { code: 'PLUGIN_ERROR'; plugin: string; message: string }\n | { code: 'DB_ERROR'; message: string }\n | { code: 'CONFIG_ERROR'; message: string }\n | { code: 'VALIDATION_ERROR'; message: string; details?: unknown };\n\nexport type TraceMcpResult<T> = Result<T, TraceMcpError>;\n\nexport function parseError(file: string, message: string, partial = false): TraceMcpError {\n return { code: 'PARSE_ERROR', file, partial, message };\n}\n\nexport function notFound(id: string, candidates?: string[]): TraceMcpError {\n return { code: 'NOT_FOUND', id, candidates };\n}\n\nexport function securityViolation(detail: string): TraceMcpError {\n return { code: 'SECURITY_VIOLATION', detail };\n}\n\nexport function pluginError(plugin: string, message: string): TraceMcpError {\n return { code: 'PLUGIN_ERROR', plugin, message };\n}\n\nexport function dbError(message: string): TraceMcpError {\n return { code: 'DB_ERROR', message };\n}\n\nexport function configError(message: string): TraceMcpError {\n return { code: 'CONFIG_ERROR', message };\n}\n\nexport function validationError(message: string, details?: unknown): TraceMcpError {\n return { code: 'VALIDATION_ERROR', message, details };\n}\n\nexport function formatToolError(error: TraceMcpError): object {\n const base: Record<string, unknown> = {\n code: error.code,\n message: 'message' in error ? error.message : ('detail' in error ? error.detail : error.code),\n };\n\n if (error.code === 'NOT_FOUND' && error.candidates?.length) {\n base.suggestions = error.candidates;\n base.help = 'Use search() to find the correct symbol_id';\n }\n\n return { error: base };\n}\n\nexport { ok, err, Result };\n","import type Database from 'better-sqlite3';\nimport type { RawSymbol, RawEdge, RawRoute, RawComponent, RawMigration, RawOrmModel, RawOrmAssociation, RawRnScreen } from '../plugin-api/types.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { dbError } from '../errors.js';\n\nexport class Store {\n constructor(public readonly db: Database.Database) {}\n\n // --- Files ---\n\n insertFile(\n path: string,\n language: string | null,\n contentHash: string | null,\n byteLength: number | null,\n workspace?: string | null,\n ): number {\n const result = this.db.prepare(\n `INSERT INTO files (path, language, content_hash, byte_length, indexed_at, workspace)\n VALUES (?, ?, ?, ?, datetime('now'), ?)`,\n ).run(path, language, contentHash, byteLength, workspace ?? null);\n const fileId = Number(result.lastInsertRowid);\n\n // Create node in unified address space\n this.createNode('file', fileId);\n return fileId;\n }\n\n getFile(path: string): FileRow | undefined {\n return this.db.prepare('SELECT * FROM files WHERE path = ?').get(path) as FileRow | undefined;\n }\n\n getFileById(id: number): FileRow | undefined {\n return this.db.prepare('SELECT * FROM files WHERE id = ?').get(id) as FileRow | undefined;\n }\n\n getAllFiles(): FileRow[] {\n return this.db.prepare('SELECT * FROM files').all() as FileRow[];\n }\n\n updateFileWorkspace(fileId: number, workspace: string): void {\n this.db.prepare('UPDATE files SET workspace = ? WHERE id = ?').run(workspace, fileId);\n }\n\n getFilesByWorkspace(workspace: string): FileRow[] {\n return this.db.prepare('SELECT * FROM files WHERE workspace = ?').all(workspace) as FileRow[];\n }\n\n updateFileHash(fileId: number, hash: string, byteLength: number): void {\n this.db.prepare(\n \"UPDATE files SET content_hash = ?, byte_length = ?, indexed_at = datetime('now') WHERE id = ?\",\n ).run(hash, byteLength, fileId);\n }\n\n updateFileStatus(fileId: number, status: string, frameworkRole?: string): void {\n this.db.prepare(\n 'UPDATE files SET status = ?, framework_role = COALESCE(?, framework_role) WHERE id = ?',\n ).run(status, frameworkRole ?? null, fileId);\n }\n\n deleteFile(fileId: number): void {\n // Cascade deletes symbols, edges via nodes\n this.deleteEdgesForFileNodes(fileId);\n this.deleteEntitiesByFile(fileId);\n this.db.prepare('DELETE FROM nodes WHERE node_type = ? AND ref_id = ?').run('file', fileId);\n this.db.prepare('DELETE FROM files WHERE id = ?').run(fileId);\n }\n\n /** Delete routes, components, migrations, ORM models, and RN screens for a file (and their nodes). */\n deleteEntitiesByFile(fileId: number): void {\n for (const [table, nodeType] of [\n ['routes', 'route'],\n ['components', 'component'],\n ['migrations', 'migration'],\n ['orm_models', 'orm_model'],\n ['rn_screens', 'rn_screen'],\n ] as const) {\n const ids = this.db.prepare(`SELECT id FROM ${table} WHERE file_id = ?`).all(fileId) as { id: number }[];\n if (ids.length > 0) {\n const placeholders = ids.map(() => '?').join(',');\n const idValues = ids.map((r) => r.id);\n this.db.prepare(`DELETE FROM nodes WHERE node_type = ? AND ref_id IN (${placeholders})`).run(nodeType, ...idValues);\n this.db.prepare(`DELETE FROM ${table} WHERE file_id = ?`).run(fileId);\n }\n }\n }\n\n // --- Symbols ---\n\n insertSymbol(fileId: number, sym: RawSymbol): number {\n const parentId = sym.parentSymbolId\n ? (this.db.prepare('SELECT id FROM symbols WHERE symbol_id = ?').get(sym.parentSymbolId) as { id: number } | undefined)?.id ?? null\n : null;\n\n const result = this.db.prepare(\n `INSERT OR REPLACE INTO symbols (file_id, symbol_id, name, kind, fqn, parent_id, signature, byte_start, byte_end, line_start, line_end, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n fileId,\n sym.symbolId,\n sym.name,\n sym.kind,\n sym.fqn ?? null,\n parentId,\n sym.signature ?? null,\n sym.byteStart,\n sym.byteEnd,\n sym.lineStart ?? null,\n sym.lineEnd ?? null,\n sym.metadata ? JSON.stringify(sym.metadata) : null,\n );\n\n const symbolId = Number(result.lastInsertRowid);\n this.createNode('symbol', symbolId);\n return symbolId;\n }\n\n insertSymbols(fileId: number, symbols: RawSymbol[]): number[] {\n return this.db.transaction(() => {\n return symbols.map((s) => this.insertSymbol(fileId, s));\n })();\n }\n\n deleteSymbolsByFile(fileId: number): void {\n // Single subquery instead of N individual per-symbol DELETEs\n this.db.prepare(\n `DELETE FROM nodes WHERE node_type = 'symbol'\n AND ref_id IN (SELECT id FROM symbols WHERE file_id = ?)`,\n ).run(fileId);\n this.db.prepare('DELETE FROM symbols WHERE file_id = ?').run(fileId);\n }\n\n getSymbolsByFile(fileId: number): SymbolRow[] {\n return this.db.prepare('SELECT * FROM symbols WHERE file_id = ? ORDER BY byte_start').all(fileId) as SymbolRow[];\n }\n\n getSymbolBySymbolId(symbolId: string): SymbolRow | undefined {\n return this.db.prepare('SELECT * FROM symbols WHERE symbol_id = ?').get(symbolId) as SymbolRow | undefined;\n }\n\n getSymbolByFqn(fqn: string): SymbolRow | undefined {\n return this.db.prepare('SELECT * FROM symbols WHERE fqn = ?').get(fqn) as SymbolRow | undefined;\n }\n\n // --- Nodes ---\n\n createNode(nodeType: string, refId: number): number {\n const existing = this.db.prepare(\n 'SELECT id FROM nodes WHERE node_type = ? AND ref_id = ?',\n ).get(nodeType, refId) as { id: number } | undefined;\n\n if (existing) return existing.id;\n\n const result = this.db.prepare(\n 'INSERT INTO nodes (node_type, ref_id) VALUES (?, ?)',\n ).run(nodeType, refId);\n return Number(result.lastInsertRowid);\n }\n\n getNodeId(nodeType: string, refId: number): number | undefined {\n const row = this.db.prepare(\n 'SELECT id FROM nodes WHERE node_type = ? AND ref_id = ?',\n ).get(nodeType, refId) as { id: number } | undefined;\n return row?.id;\n }\n\n // --- Edges ---\n\n insertEdge(\n sourceNodeId: number,\n targetNodeId: number,\n edgeTypeName: string,\n resolved = true,\n metadata?: Record<string, unknown>,\n isCrossWs = false,\n ): TraceMcpResult<number> {\n const edgeType = this.db.prepare('SELECT id FROM edge_types WHERE name = ?').get(edgeTypeName) as { id: number } | undefined;\n if (!edgeType) {\n return err(dbError(`Unknown edge type: ${edgeTypeName}`));\n }\n\n try {\n const result = this.db.prepare(\n `INSERT OR IGNORE INTO edges (source_node_id, target_node_id, edge_type_id, resolved, metadata, is_cross_ws)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(sourceNodeId, targetNodeId, edgeType.id, resolved ? 1 : 0, metadata ? JSON.stringify(metadata) : null, isCrossWs ? 1 : 0);\n return ok(Number(result.lastInsertRowid));\n } catch (e) {\n return err(dbError(e instanceof Error ? e.message : String(e)));\n }\n }\n\n deleteEdgesForFileNodes(fileId: number): void {\n // Collect all node IDs for this file's symbols + file node in a single subquery\n this.db.prepare(`\n DELETE FROM edges WHERE source_node_id IN (\n SELECT n.id FROM nodes n\n WHERE (n.node_type = 'file' AND n.ref_id = ?)\n OR (n.node_type = 'symbol' AND n.ref_id IN (SELECT id FROM symbols WHERE file_id = ?))\n ) OR target_node_id IN (\n SELECT n.id FROM nodes n\n WHERE (n.node_type = 'file' AND n.ref_id = ?)\n OR (n.node_type = 'symbol' AND n.ref_id IN (SELECT id FROM symbols WHERE file_id = ?))\n )\n `).run(fileId, fileId, fileId, fileId);\n }\n\n // --- Graph Traversal ---\n\n traverseEdges(startNodeId: number, direction: 'outgoing' | 'incoming', depth: number): EdgeRow[] {\n const directionCol = direction === 'outgoing' ? 'source_node_id' : 'target_node_id';\n const otherCol = direction === 'outgoing' ? 'target_node_id' : 'source_node_id';\n\n const sql = `\n WITH RECURSIVE traverse(node_id, depth) AS (\n SELECT ?, 0\n UNION ALL\n SELECT e.${otherCol}, t.depth + 1\n FROM edges e\n JOIN traverse t ON e.${directionCol} = t.node_id\n WHERE t.depth < ?\n )\n SELECT DISTINCT e.*\n FROM traverse t\n JOIN edges e ON e.${directionCol} = t.node_id\n WHERE t.depth < ?\n `;\n\n return this.db.prepare(sql).all(startNodeId, depth, depth) as EdgeRow[];\n }\n\n // --- Routes ---\n\n insertRoute(route: RawRoute, fileId: number): number {\n // controller_symbol_id is an INTEGER FK to symbols.id\n // If controllerSymbolId is a string FQN ref, we store null for the FK\n // and encode it in the middleware JSON as { middleware: [...], controllerRef: \"...\" }\n let resolvedControllerSymId: number | null = null;\n let controllerRef: string | undefined;\n\n if (route.controllerSymbolId) {\n const asNum = Number(route.controllerSymbolId);\n if (!isNaN(asNum)) {\n resolvedControllerSymId = asNum;\n } else {\n controllerRef = route.controllerSymbolId;\n }\n }\n\n // Encode middleware + optional controllerRef together\n const mwArray = route.middleware ?? [];\n let middlewareJson: string | null = null;\n if (controllerRef || mwArray.length > 0) {\n middlewareJson = JSON.stringify({\n middleware: mwArray,\n ...(controllerRef ? { controllerRef } : {}),\n });\n }\n\n const result = this.db.prepare(\n `INSERT INTO routes (method, uri, name, controller_symbol_id, middleware, file_id, line)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n route.method,\n route.uri,\n route.name ?? null,\n resolvedControllerSymId,\n middlewareJson,\n fileId,\n route.line ?? null,\n );\n const routeId = Number(result.lastInsertRowid);\n this.createNode('route', routeId);\n return routeId;\n }\n\n // --- Components ---\n\n insertComponent(comp: RawComponent, fileId: number): number {\n const result = this.db.prepare(\n `INSERT INTO components (file_id, name, kind, props, emits, slots, composables, framework)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n fileId,\n comp.name,\n comp.kind,\n comp.props ? JSON.stringify(comp.props) : null,\n comp.emits ? JSON.stringify(comp.emits) : null,\n comp.slots ? JSON.stringify(comp.slots) : null,\n comp.composables ? JSON.stringify(comp.composables) : null,\n comp.framework,\n );\n const compId = Number(result.lastInsertRowid);\n this.createNode('component', compId);\n return compId;\n }\n\n getComponentByFileId(fileId: number): ComponentRow | undefined {\n return this.db.prepare('SELECT * FROM components WHERE file_id = ?').get(fileId) as ComponentRow | undefined;\n }\n\n getComponentByName(name: string): ComponentRow | undefined {\n return this.db.prepare('SELECT * FROM components WHERE name = ?').get(name) as ComponentRow | undefined;\n }\n\n getAllComponents(): ComponentRow[] {\n return this.db.prepare('SELECT * FROM components').all() as ComponentRow[];\n }\n\n /** Ensure an edge type exists in the database, inserting if missing. */\n ensureEdgeType(name: string, category: string, description: string): void {\n this.db.prepare(\n 'INSERT OR IGNORE INTO edge_types (name, category, directed, description) VALUES (?, ?, 1, ?)',\n ).run(name, category, description);\n }\n\n /** Get the edge type name by its id */\n getEdgeTypeName(edgeTypeId: number): string | undefined {\n const row = this.db.prepare('SELECT name FROM edge_types WHERE id = ?').get(edgeTypeId) as { name: string } | undefined;\n return row?.name;\n }\n\n /** Reverse-lookup: find which symbol/file a node refers to */\n getNodeRef(nodeId: number): { nodeType: string; refId: number } | undefined {\n return this.db.prepare('SELECT node_type AS nodeType, ref_id AS refId FROM nodes WHERE id = ?').get(nodeId) as { nodeType: string; refId: number } | undefined;\n }\n\n // --- Migrations ---\n\n insertMigration(mig: RawMigration, fileId: number): number {\n const result = this.db.prepare(\n `INSERT INTO migrations (file_id, table_name, operation, columns, indices, timestamp)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(\n fileId,\n mig.tableName,\n mig.operation,\n mig.columns ? JSON.stringify(mig.columns) : null,\n mig.indices ? JSON.stringify(mig.indices) : null,\n mig.timestamp ?? null,\n );\n const migId = Number(result.lastInsertRowid);\n this.createNode('migration', migId);\n return migId;\n }\n\n // --- Route queries ---\n\n getRouteByUriAndMethod(uri: string, method: string): RouteRow | undefined {\n return this.db.prepare(\n 'SELECT * FROM routes WHERE uri = ? AND method = ?',\n ).get(uri, method) as RouteRow | undefined;\n }\n\n getAllRoutes(): RouteRow[] {\n return this.db.prepare('SELECT * FROM routes').all() as RouteRow[];\n }\n\n findRouteByPattern(uri: string, method: string): RouteRow | undefined {\n const likePattern = uri.replace(/\\{[^}]+\\}/g, '%');\n const routes = this.db.prepare(\n 'SELECT * FROM routes WHERE method = ? AND uri LIKE ?',\n ).all(method.toUpperCase(), likePattern) as RouteRow[];\n const exact = routes.find((r) => r.uri === uri);\n return exact ?? routes[0];\n }\n\n // --- Migration queries ---\n\n getMigrationsByTable(tableName: string): MigrationRow[] {\n return this.db.prepare(\n 'SELECT * FROM migrations WHERE table_name = ? ORDER BY timestamp ASC',\n ).all(tableName) as MigrationRow[];\n }\n\n getAllMigrations(): MigrationRow[] {\n return this.db.prepare(\n 'SELECT * FROM migrations ORDER BY timestamp ASC',\n ).all() as MigrationRow[];\n }\n\n // --- Edge queries ---\n\n getEdgesByType(edgeTypeName: string): EdgeRow[] {\n const edgeType = this.db.prepare(\n 'SELECT id FROM edge_types WHERE name = ?',\n ).get(edgeTypeName) as { id: number } | undefined;\n if (!edgeType) return [];\n return this.db.prepare(\n 'SELECT * FROM edges WHERE edge_type_id = ?',\n ).all(edgeType.id) as EdgeRow[];\n }\n\n getOutgoingEdges(nodeId: number): (EdgeRow & { edge_type_name: string })[] {\n return this.db.prepare(\n `SELECT e.*, et.name as edge_type_name\n FROM edges e JOIN edge_types et ON e.edge_type_id = et.id\n WHERE e.source_node_id = ?`,\n ).all(nodeId) as (EdgeRow & { edge_type_name: string })[];\n }\n\n getIncomingEdges(nodeId: number): (EdgeRow & { edge_type_name: string })[] {\n return this.db.prepare(\n `SELECT e.*, et.name as edge_type_name\n FROM edges e JOIN edge_types et ON e.edge_type_id = et.id\n WHERE e.target_node_id = ?`,\n ).all(nodeId) as (EdgeRow & { edge_type_name: string })[];\n }\n\n // --- ORM Models ---\n\n insertOrmModel(model: RawOrmModel, fileId: number): number {\n const result = this.db.prepare(\n `INSERT INTO orm_models (file_id, name, orm, collection_or_table, fields, options, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n fileId,\n model.name,\n model.orm,\n model.collectionOrTable ?? null,\n model.fields ? JSON.stringify(model.fields) : null,\n model.options ? JSON.stringify(model.options) : null,\n model.metadata ? JSON.stringify(model.metadata) : null,\n );\n const modelId = Number(result.lastInsertRowid);\n this.createNode('orm_model', modelId);\n return modelId;\n }\n\n getOrmModelByName(name: string): OrmModelRow | undefined {\n return this.db.prepare('SELECT * FROM orm_models WHERE name = ?').get(name) as OrmModelRow | undefined;\n }\n\n getOrmModelsByOrm(orm: string): OrmModelRow[] {\n return this.db.prepare('SELECT * FROM orm_models WHERE orm = ?').all(orm) as OrmModelRow[];\n }\n\n getAllOrmModels(): OrmModelRow[] {\n return this.db.prepare('SELECT * FROM orm_models').all() as OrmModelRow[];\n }\n\n // --- ORM Associations ---\n\n insertOrmAssociation(\n sourceModelId: number,\n targetModelId: number | null,\n targetModelName: string,\n kind: string,\n options?: Record<string, unknown>,\n fileId?: number,\n line?: number,\n ): number {\n const result = this.db.prepare(\n `INSERT INTO orm_associations (source_model_id, target_model_id, target_model_name, kind, options, file_id, line)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n sourceModelId,\n targetModelId,\n targetModelName,\n kind,\n options ? JSON.stringify(options) : null,\n fileId ?? null,\n line ?? null,\n );\n return Number(result.lastInsertRowid);\n }\n\n getAllOrmAssociations(): OrmAssociationRow[] {\n return this.db.prepare('SELECT * FROM orm_associations').all() as OrmAssociationRow[];\n }\n\n getOrmAssociationsByModel(modelId: number): OrmAssociationRow[] {\n return this.db.prepare(\n 'SELECT * FROM orm_associations WHERE source_model_id = ?',\n ).all(modelId) as OrmAssociationRow[];\n }\n\n // --- React Native Screens ---\n\n insertRnScreen(screen: RawRnScreen, fileId: number): number {\n const result = this.db.prepare(\n `INSERT INTO rn_screens (file_id, name, component_path, navigator_type, options, deep_link, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n fileId,\n screen.name,\n screen.componentPath ?? null,\n screen.navigatorType ?? null,\n screen.options ? JSON.stringify(screen.options) : null,\n screen.deepLink ?? null,\n screen.metadata ? JSON.stringify(screen.metadata) : null,\n );\n const screenId = Number(result.lastInsertRowid);\n this.createNode('rn_screen', screenId);\n return screenId;\n }\n\n getRnScreenByName(name: string): RnScreenRow | undefined {\n return this.db.prepare('SELECT * FROM rn_screens WHERE name = ?').get(name) as RnScreenRow | undefined;\n }\n\n getAllRnScreens(): RnScreenRow[] {\n return this.db.prepare('SELECT * FROM rn_screens').all() as RnScreenRow[];\n }\n\n getSymbolById(id: number): SymbolRow | undefined {\n return this.db.prepare('SELECT * FROM symbols WHERE id = ?').get(id) as SymbolRow | undefined;\n }\n\n getNodeByNodeId(nodeId: number): { node_type: string; ref_id: number } | undefined {\n return this.db.prepare(\n 'SELECT node_type, ref_id FROM nodes WHERE id = ?',\n ).get(nodeId) as { node_type: string; ref_id: number } | undefined;\n }\n\n // --- Introspection queries ---\n\n findImplementors(name: string): SymbolWithFilePath[] {\n return this.db.prepare(\n `SELECT s.*, f.path as file_path\n FROM symbols s\n JOIN files f ON s.file_id = f.id\n WHERE s.metadata IS NOT NULL AND (\n json_extract(s.metadata, '$.implements') LIKE '%\"' || ? || '\"%'\n OR json_extract(s.metadata, '$.extends') LIKE '%\"' || ? || '\"%'\n OR json_extract(s.metadata, '$.extends') = ?\n )`,\n ).all(name, name, name) as SymbolWithFilePath[];\n }\n\n getExportedSymbols(filePattern?: string): SymbolWithFilePath[] {\n if (filePattern) {\n const likePattern = filePattern.replace(/\\*/g, '%').replace(/\\?/g, '_');\n return this.db.prepare(\n `SELECT s.*, f.path as file_path\n FROM symbols s\n JOIN files f ON s.file_id = f.id\n WHERE json_extract(s.metadata, '$.exported') = 1\n AND f.path LIKE ?`,\n ).all(likePattern) as SymbolWithFilePath[];\n }\n return this.db.prepare(\n `SELECT s.*, f.path as file_path\n FROM symbols s\n JOIN files f ON s.file_id = f.id\n WHERE json_extract(s.metadata, '$.exported') = 1`,\n ).all() as SymbolWithFilePath[];\n }\n\n getEdgeTypes(): EdgeTypeRow[] {\n return this.db.prepare(\n `SELECT name, category, COALESCE(description, '') as description FROM edge_types ORDER BY name`,\n ).all() as EdgeTypeRow[];\n }\n\n /**\n * Get all symbols that have heritage metadata (extends/implements).\n * Used by the TypeScript heritage resolver in the pipeline.\n */\n getSymbolsWithHeritage(): (SymbolRow & { file_path: string })[] {\n return this.db.prepare(`\n SELECT s.*, f.path AS file_path\n FROM symbols s\n JOIN files f ON s.file_id = f.id\n WHERE s.metadata IS NOT NULL\n AND (json_extract(s.metadata, '$.extends') IS NOT NULL\n OR json_extract(s.metadata, '$.implements') IS NOT NULL)\n `).all() as (SymbolRow & { file_path: string })[];\n }\n\n /**\n * Find a symbol by name and optional kind.\n * Returns the first match (prefers exact name match over substring).\n */\n getSymbolByName(name: string, kind?: string): SymbolRow | undefined {\n if (kind) {\n return this.db.prepare(\n 'SELECT * FROM symbols WHERE name = ? AND kind = ? LIMIT 1',\n ).get(name, kind) as SymbolRow | undefined;\n }\n return this.db.prepare(\n 'SELECT * FROM symbols WHERE name = ? LIMIT 1',\n ).get(name) as SymbolRow | undefined;\n }\n\n // --- Batch queries (avoid N+1) ---\n\n /** Resolve multiple node IDs in one query. Returns Map<refId, nodeId>. */\n getNodeIdsBatch(nodeType: string, refIds: number[]): Map<number, number> {\n const map = new Map<number, number>();\n if (refIds.length === 0) return map;\n const placeholders = refIds.map(() => '?').join(',');\n const rows = this.db.prepare(\n `SELECT ref_id, id FROM nodes WHERE node_type = ? AND ref_id IN (${placeholders})`,\n ).all(nodeType, ...refIds) as { ref_id: number; id: number }[];\n for (const row of rows) map.set(row.ref_id, row.id);\n return map;\n }\n\n /** Resolve multiple node refs in one query. Returns Map<nodeId, {nodeType, refId}>. */\n getNodeRefsBatch(nodeIds: number[]): Map<number, { nodeType: string; refId: number }> {\n const map = new Map<number, { nodeType: string; refId: number }>();\n if (nodeIds.length === 0) return map;\n const placeholders = nodeIds.map(() => '?').join(',');\n const rows = this.db.prepare(\n `SELECT id, node_type, ref_id FROM nodes WHERE id IN (${placeholders})`,\n ).all(...nodeIds) as { id: number; node_type: string; ref_id: number }[];\n for (const row of rows) map.set(row.id, { nodeType: row.node_type, refId: row.ref_id });\n return map;\n }\n\n /** Batch-fetch symbols by internal IDs. Returns Map<id, SymbolRow>. */\n getSymbolsByIds(ids: number[]): Map<number, SymbolRow> {\n const map = new Map<number, SymbolRow>();\n if (ids.length === 0) return map;\n const placeholders = ids.map(() => '?').join(',');\n const rows = this.db.prepare(\n `SELECT * FROM symbols WHERE id IN (${placeholders})`,\n ).all(...ids) as SymbolRow[];\n for (const row of rows) map.set(row.id, row);\n return map;\n }\n\n /** Batch-fetch files by internal IDs. Returns Map<id, FileRow>. */\n getFilesByIds(ids: number[]): Map<number, FileRow> {\n const map = new Map<number, FileRow>();\n if (ids.length === 0) return map;\n const placeholders = ids.map(() => '?').join(',');\n const rows = this.db.prepare(\n `SELECT * FROM files WHERE id IN (${placeholders})`,\n ).all(...ids) as FileRow[];\n for (const row of rows) map.set(row.id, row);\n return map;\n }\n\n /**\n * Fetch all edges where any of the given node IDs appear as source or target.\n * Returns edges annotated with edge_type_name and the pivot node id (the one from the input set).\n */\n getEdgesForNodesBatch(\n nodeIds: number[],\n ): Array<EdgeRow & { edge_type_name: string; pivot_node_id: number }> {\n if (nodeIds.length === 0) return [];\n const placeholders = nodeIds.map(() => '?').join(',');\n const rows = this.db.prepare(\n `SELECT e.*, et.name AS edge_type_name\n FROM edges e\n JOIN edge_types et ON e.edge_type_id = et.id\n WHERE e.source_node_id IN (${placeholders})\n OR e.target_node_id IN (${placeholders})`,\n ).all(...nodeIds, ...nodeIds) as (EdgeRow & { edge_type_name: string })[];\n\n const nodeSet = new Set(nodeIds);\n return rows.map((row) => ({\n ...row,\n pivot_node_id: nodeSet.has(row.source_node_id) ? row.source_node_id : row.target_node_id,\n }));\n }\n\n /** Find a class/interface symbol by name with optional framework_role filter. Single query with JOIN. */\n findSymbolByRole(name: string, frameworkRole?: string): SymbolRow | undefined {\n if (frameworkRole) {\n return this.db.prepare(\n `SELECT s.* FROM symbols s\n JOIN files f ON s.file_id = f.id\n WHERE f.framework_role = ?\n AND (s.name = ? OR s.fqn LIKE ?)\n LIMIT 1`,\n ).get(frameworkRole, name, `%\\\\${name}`) as SymbolRow | undefined;\n }\n return this.db.prepare(\n 'SELECT * FROM symbols WHERE name = ? AND kind = ? LIMIT 1',\n ).get(name, 'class') as SymbolRow | undefined;\n }\n\n // --- Env vars ---\n\n insertEnvVar(fileId: number, entry: {\n key: string;\n valueType: string;\n valueFormat: string | null;\n comment: string | null;\n quoted: boolean;\n line: number;\n }): number {\n return (this.db.prepare(\n `INSERT INTO env_vars (file_id, key, value_type, value_format, comment, quoted, line)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n fileId, entry.key, entry.valueType, entry.valueFormat,\n entry.comment, entry.quoted ? 1 : 0, entry.line,\n ) as { lastInsertRowid: number }).lastInsertRowid as number;\n }\n\n deleteEnvVarsByFile(fileId: number): void {\n this.db.prepare('DELETE FROM env_vars WHERE file_id = ?').run(fileId);\n }\n\n getEnvVarsByFile(fileId: number): EnvVarRow[] {\n return this.db.prepare(\n 'SELECT * FROM env_vars WHERE file_id = ? ORDER BY line',\n ).all(fileId) as EnvVarRow[];\n }\n\n getAllEnvVars(): (EnvVarRow & { file_path: string })[] {\n return this.db.prepare(\n `SELECT ev.*, f.path as file_path\n FROM env_vars ev\n JOIN files f ON ev.file_id = f.id\n ORDER BY f.path, ev.line`,\n ).all() as (EnvVarRow & { file_path: string })[];\n }\n\n searchEnvVars(pattern: string): (EnvVarRow & { file_path: string })[] {\n return this.db.prepare(\n `SELECT ev.*, f.path as file_path\n FROM env_vars ev\n JOIN files f ON ev.file_id = f.id\n WHERE ev.key LIKE ?\n ORDER BY f.path, ev.line`,\n ).all(`%${pattern}%`) as (EnvVarRow & { file_path: string })[];\n }\n\n // --- AI Summarization ---\n\n updateSymbolSummary(symbolId: number, summary: string): void {\n this.db.prepare('UPDATE symbols SET summary = ? WHERE id = ?').run(summary, symbolId);\n }\n\n getUnsummarizedSymbols(kinds: string[], limit: number): {\n id: number;\n name: string;\n fqn: string | null;\n kind: string;\n signature: string | null;\n file_path: string;\n byte_start: number;\n byte_end: number;\n }[] {\n if (kinds.length === 0) return [];\n const placeholders = kinds.map(() => '?').join(',');\n return this.db.prepare(`\n SELECT s.id, s.name, s.fqn, s.kind, s.signature, f.path as file_path, s.byte_start, s.byte_end\n FROM symbols s\n JOIN files f ON s.file_id = f.id\n WHERE s.summary IS NULL AND s.kind IN (${placeholders})\n LIMIT ?\n `).all(...kinds, limit) as {\n id: number;\n name: string;\n fqn: string | null;\n kind: string;\n signature: string | null;\n file_path: string;\n byte_start: number;\n byte_end: number;\n }[];\n }\n\n // --- Stats ---\n\n getStats(): IndexStats {\n const fileCount = (this.db.prepare('SELECT COUNT(*) as c FROM files').get() as { c: number }).c;\n const symbolCount = (this.db.prepare('SELECT COUNT(*) as c FROM symbols').get() as { c: number }).c;\n const edgeCount = (this.db.prepare('SELECT COUNT(*) as c FROM edges').get() as { c: number }).c;\n const nodeCount = (this.db.prepare('SELECT COUNT(*) as c FROM nodes').get() as { c: number }).c;\n const routeCount = (this.db.prepare('SELECT COUNT(*) as c FROM routes').get() as { c: number }).c;\n const componentCount = (this.db.prepare('SELECT COUNT(*) as c FROM components').get() as { c: number }).c;\n const migrationCount = (this.db.prepare('SELECT COUNT(*) as c FROM migrations').get() as { c: number }).c;\n\n const partialFiles = (this.db.prepare(\"SELECT COUNT(*) as c FROM files WHERE status = 'partial'\").get() as { c: number }).c;\n const errorFiles = (this.db.prepare(\"SELECT COUNT(*) as c FROM files WHERE status = 'error'\").get() as { c: number }).c;\n\n return {\n totalFiles: fileCount,\n totalSymbols: symbolCount,\n totalEdges: edgeCount,\n totalNodes: nodeCount,\n totalRoutes: routeCount,\n totalComponents: componentCount,\n totalMigrations: migrationCount,\n partialFiles,\n errorFiles,\n };\n }\n}\n\n// --- Row types ---\n\nexport interface FileRow {\n id: number;\n path: string;\n language: string | null;\n framework_role: string | null;\n status: string;\n content_hash: string | null;\n byte_length: number | null;\n indexed_at: string;\n metadata: string | null;\n workspace: string | null;\n}\n\nexport interface SymbolRow {\n id: number;\n file_id: number;\n symbol_id: string;\n name: string;\n kind: string;\n fqn: string | null;\n parent_id: number | null;\n signature: string | null;\n summary: string | null;\n byte_start: number;\n byte_end: number;\n line_start: number | null;\n line_end: number | null;\n metadata: string | null;\n}\n\nexport interface EdgeRow {\n id: number;\n source_node_id: number;\n target_node_id: number;\n edge_type_id: number;\n resolved: number;\n metadata: string | null;\n is_cross_ws: number;\n}\n\nexport interface RouteRow {\n id: number;\n method: string;\n uri: string;\n name: string | null;\n handler: string | null;\n controller_symbol_id: string | null;\n middleware: string | null;\n metadata: string | null;\n file_id: number | null;\n line: number | null;\n}\n\nexport interface MigrationRow {\n id: number;\n file_id: number;\n table_name: string;\n operation: string;\n columns: string | null;\n indices: string | null;\n timestamp: string | null;\n}\n\nexport interface ComponentRow {\n id: number;\n file_id: number;\n name: string;\n kind: string;\n props: string | null;\n emits: string | null;\n slots: string | null;\n composables: string | null;\n framework: string;\n}\n\nexport interface OrmModelRow {\n id: number;\n file_id: number;\n name: string;\n orm: string;\n collection_or_table: string | null;\n fields: string | null;\n options: string | null;\n metadata: string | null;\n}\n\nexport interface OrmAssociationRow {\n id: number;\n source_model_id: number;\n target_model_id: number | null;\n target_model_name: string | null;\n kind: string;\n options: string | null;\n file_id: number | null;\n line: number | null;\n}\n\nexport interface RnScreenRow {\n id: number;\n file_id: number;\n name: string;\n component_path: string | null;\n navigator_type: string | null;\n options: string | null;\n deep_link: string | null;\n metadata: string | null;\n}\n\nexport interface EnvVarRow {\n id: number;\n file_id: number;\n key: string;\n value_type: string;\n value_format: string | null;\n comment: string | null;\n quoted: number;\n line: number | null;\n}\n\nexport interface SymbolWithFilePath extends SymbolRow {\n file_path: string;\n}\n\nexport interface EdgeTypeRow {\n name: string;\n category: string;\n description: string;\n}\n\nexport interface IndexStats {\n totalFiles: number;\n totalSymbols: number;\n totalEdges: number;\n totalNodes: number;\n totalRoutes: number;\n totalComponents: number;\n totalMigrations: number;\n partialFiles: number;\n errorFiles: number;\n}\n","import type { LanguagePlugin, FrameworkPlugin, PluginManifest, ProjectContext } from './types.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { pluginError } from '../errors.js';\n\nexport class PluginRegistry {\n private languagePlugins: LanguagePlugin[] = [];\n private frameworkPlugins: FrameworkPlugin[] = [];\n\n registerLanguagePlugin(plugin: LanguagePlugin): void {\n this.languagePlugins.push(plugin);\n }\n\n registerFrameworkPlugin(plugin: FrameworkPlugin): void {\n this.frameworkPlugins.push(plugin);\n }\n\n getLanguagePlugins(): LanguagePlugin[] {\n return this.sortByPriority(this.languagePlugins);\n }\n\n getActiveFrameworkPlugins(ctx: ProjectContext): TraceMcpResult<FrameworkPlugin[]> {\n const active = this.frameworkPlugins.filter((p) => p.detect(ctx));\n return this.topologicalSort(active);\n }\n\n getAllFrameworkPlugins(): FrameworkPlugin[] {\n return [...this.frameworkPlugins];\n }\n\n getLanguagePluginForFile(filePath: string): LanguagePlugin | undefined {\n const ext = filePath.slice(filePath.lastIndexOf('.'));\n const sorted = this.getLanguagePlugins();\n return sorted.find((p) => p.supportedExtensions.includes(ext));\n }\n\n private sortByPriority<T extends { manifest: PluginManifest }>(plugins: T[]): T[] {\n return [...plugins].sort((a, b) => a.manifest.priority - b.manifest.priority);\n }\n\n private topologicalSort(plugins: FrameworkPlugin[]): TraceMcpResult<FrameworkPlugin[]> {\n const nameMap = new Map<string, FrameworkPlugin>();\n for (const p of plugins) {\n nameMap.set(p.manifest.name, p);\n }\n\n const sorted: FrameworkPlugin[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n\n const visit = (plugin: FrameworkPlugin): TraceMcpResult<void> => {\n const name = plugin.manifest.name;\n\n if (visiting.has(name)) {\n return err(\n pluginError(name, `Circular dependency detected involving plugin '${name}'`),\n );\n }\n\n if (visited.has(name)) return ok(undefined);\n\n visiting.add(name);\n\n for (const depName of plugin.manifest.dependencies ?? []) {\n const dep = nameMap.get(depName);\n if (dep) {\n const result = visit(dep);\n if (result.isErr()) return result;\n }\n // Missing dependency in active set is not an error — it may not be detected\n }\n\n visiting.delete(name);\n visited.add(name);\n sorted.push(plugin);\n\n return ok(undefined);\n };\n\n // Sort by priority first, then topological sort\n const prioritySorted = this.sortByPriority(plugins);\n for (const plugin of prioritySorted) {\n const result = visit(plugin);\n if (result.isErr()) return err(result.error);\n }\n\n return ok(sorted);\n }\n}\n","import { cosmiconfig } from 'cosmiconfig';\nimport { z } from 'zod';\nimport { ok, err, type TraceMcpResult } from './errors.js';\nimport { configError } from './errors.js';\nimport { logger } from './logger.js';\n\nconst SecurityConfigSchema = z.object({\n secret_patterns: z.array(z.string()).optional(),\n max_file_size_bytes: z.number().positive().optional(),\n}).optional();\n\nconst ArtisanConfigSchema = z.object({\n enabled: z.boolean().default(true),\n timeout: z.number().positive().default(10000),\n}).optional();\n\nconst FrameworkConfigSchema = z.object({\n laravel: z.object({\n artisan: ArtisanConfigSchema,\n graceful_degradation: z.boolean().default(true),\n }).optional(),\n}).optional();\n\nconst AiConfigSchema = z.object({\n enabled: z.boolean().default(false),\n provider: z.enum(['ollama', 'openai']).default('ollama'),\n base_url: z.string().optional(),\n api_key: z.string().optional(),\n inference_model: z.string().optional(),\n fast_model: z.string().optional(),\n embedding_model: z.string().optional(),\n embedding_dimensions: z.number().optional(),\n summarize_on_index: z.boolean().default(true),\n summarize_batch_size: z.number().positive().default(20),\n summarize_kinds: z.array(z.string()).default([\n 'class', 'function', 'method', 'interface', 'trait', 'enum', 'type',\n ]),\n reranker_model: z.string().optional(),\n}).optional();\n\nexport const TraceMcpConfigSchema = z.object({\n root: z.string().default('.'),\n include: z.array(z.string()).default([\n 'app/**/*.php',\n 'routes/**/*.php',\n 'database/migrations/**/*.php',\n 'resources/js/**/*.{vue,ts,tsx,js,jsx}',\n 'resources/views/**/*.blade.php',\n ]),\n exclude: z.array(z.string()).default([\n 'vendor/**', 'node_modules/**', '.git/**',\n 'storage/**', 'bootstrap/cache/**', '.nuxt/**',\n '**/.env', '**/.env.*',\n ]),\n db: z.object({\n path: z.string().default('.trace-mcp/index.db'),\n }).default({}),\n frameworks: FrameworkConfigSchema,\n ai: AiConfigSchema,\n plugins: z.array(z.string()).default([]),\n security: SecurityConfigSchema,\n});\n\nexport type TraceMcpConfig = z.infer<typeof TraceMcpConfigSchema>;\n\nexport async function loadConfig(searchFrom?: string): Promise<TraceMcpResult<TraceMcpConfig>> {\n const explorer = cosmiconfig('trace-mcp', {\n searchPlaces: [\n '.trace-mcp.json',\n '.trace-mcp',\n '.config/trace-mcp.json',\n 'package.json',\n ],\n });\n\n try {\n const result = searchFrom\n ? await explorer.search(searchFrom)\n : await explorer.search();\n\n const rawConfig = result?.config ?? {};\n\n // Env var overrides\n if (process.env.TRACE_MCP_DB_PATH) {\n rawConfig.db = rawConfig.db ?? {};\n rawConfig.db.path = process.env.TRACE_MCP_DB_PATH;\n }\n\n if (process.env.TRACE_MCP_LOG_LEVEL) {\n // Log level is handled by pino directly, but note it's available\n }\n\n const parsed = TraceMcpConfigSchema.safeParse(rawConfig);\n if (!parsed.success) {\n const issues = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');\n return err(configError(`Config validation failed: ${issues}`));\n }\n\n logger.debug({ configPath: result?.filepath ?? 'defaults' }, 'Config loaded');\n return ok(parsed.data);\n } catch (e) {\n return err(configError(e instanceof Error ? e.message : String(e)));\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport type { Store } from './db/store.js';\nimport type { PluginRegistry } from './plugin-api/registry.js';\nimport type { TraceMcpConfig } from './config.js';\nimport { getIndexHealth, getProjectMap } from './tools/project.js';\nimport { getSymbol, search, getFileOutline, type SearchResultItemProjected } from './tools/navigation.js';\nimport { getComponentTree } from './tools/components.js';\nimport { getChangeImpact } from './tools/impact.js';\nimport { getFeatureContext } from './tools/context.js';\nimport { IndexingPipeline } from './indexer/pipeline.js';\nimport { formatToolError } from './errors.js';\nimport { validatePath } from './utils/security.js';\nimport { logger } from './logger.js';\nimport { createAIProvider, BlobVectorStore, type AIProvider, type RerankerService } from './ai/index.js';\nimport { LLMReranker } from './ai/reranker.js';\nimport { registerAITools } from './tools/ai-tools.js';\nimport { getMiddlewareChain } from './tools/middleware-chain.js';\nimport { getModuleGraph } from './tools/module-graph.js';\nimport { getDITree } from './tools/di-tree.js';\nimport { getNavigationGraph } from './tools/rn-navigation.js';\nimport { getScreenContext } from './tools/screen-context.js';\nimport { getRequestFlow } from './tools/flow.js';\nimport { getModelContext } from './tools/model.js';\nimport { getSchema } from './tools/schema.js';\nimport { getEventGraph } from './tools/events.js';\nimport { findReferences } from './tools/references.js';\nimport { getCallGraph } from './tools/call-graph.js';\nimport { getLivewireContext } from './tools/livewire.js';\nimport { getNovaResource } from './tools/nova.js';\nimport { getTestsFor } from './tools/tests.js';\nimport { getImplementations, getApiSurface, getPluginRegistry, getTypeHierarchy, getDeadExports, getDependencyGraph, getUntestedExports, selfAudit } from './tools/introspect.js';\n\n/** Compact JSON — no pretty-printing; saves 25–35% tokens on every response */\nfunction j(value: unknown): string {\n return JSON.stringify(value);\n}\n\nexport function createServer(\n store: Store,\n registry: PluginRegistry,\n config: TraceMcpConfig,\n rootPath?: string,\n): McpServer {\n const server = new McpServer({\n name: 'trace-mcp',\n version: '0.1.0',\n });\n\n const projectRoot = rootPath ?? process.cwd();\n\n // AI layer (optional)\n const aiProvider: AIProvider = createAIProvider(config);\n const vectorStore = config.ai?.enabled ? new BlobVectorStore(store.db) : null;\n const embeddingService = config.ai?.enabled ? aiProvider.embedding() : null;\n const reranker: RerankerService | null = config.ai?.enabled\n ? new LLMReranker(aiProvider.fastInference())\n : null;\n\n // Determine which framework plugins are registered → drives dynamic tool registration\n const frameworkNames = new Set(\n registry.getAllFrameworkPlugins().map((p) => p.manifest.name),\n );\n const has = (...names: string[]) => names.some((n) => frameworkNames.has(n));\n\n /** Validate a user-supplied path stays within projectRoot; returns error response on failure */\n function guardPath(filePath: string): { content: [{ type: 'text'; text: string }]; isError: true } | null {\n const check = validatePath(filePath, projectRoot);\n if (check.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(check.error)) }], isError: true };\n }\n return null;\n }\n\n // --- Core Tools (always registered) ---\n\n server.tool(\n 'get_index_health',\n 'Get index status, statistics, and health information',\n {},\n async () => {\n const result = getIndexHealth(store, config);\n return { content: [{ type: 'text', text: j(result) }] };\n },\n );\n\n server.tool(\n 'reindex',\n 'Trigger (re)indexing of the project or a subdirectory',\n {\n path: z.string().max(512).optional().describe('Subdirectory to index (default: project root)'),\n force: z.boolean().optional().describe('Skip hash check and reindex all files'),\n },\n async ({ path: indexPath, force }) => {\n if (indexPath) {\n const blocked = guardPath(indexPath);\n if (blocked) return blocked;\n }\n logger.info({ path: indexPath, force }, 'Reindex requested');\n const pipeline = new IndexingPipeline(store, registry, config, projectRoot);\n\n const result = indexPath\n ? await pipeline.indexFiles([indexPath])\n : await pipeline.indexAll(force ?? false);\n\n return { content: [{ type: 'text', text: j({ status: 'completed', ...result }) }] };\n },\n );\n\n server.tool(\n 'get_project_map',\n 'Get project overview: frameworks, statistics, languages. Use summary_only=true for a lightweight token-saving version.',\n {\n summary_only: z.boolean().optional().describe('Return only framework list + counts (default false)'),\n },\n async ({ summary_only }) => {\n const result = getProjectMap(store, registry, summary_only ?? false);\n return { content: [{ type: 'text', text: j(result) }] };\n },\n );\n\n // --- Env Vars Tool ---\n\n server.tool(\n 'get_env_vars',\n 'List environment variable keys from .env files with inferred value types/formats. Never exposes actual values — only keys, types (string/number/boolean/empty), and formats (url/email/ip/path/uuid/json/base64/csv/dsn/etc). Use to understand project configuration without accessing secrets.',\n {\n pattern: z.string().max(256).optional().describe('Filter keys by pattern (e.g. \"DB_\" or \"REDIS\")'),\n file: z.string().max(512).optional().describe('Filter by specific .env file path'),\n },\n async ({ pattern, file }) => {\n let vars = pattern ? store.searchEnvVars(pattern) : store.getAllEnvVars();\n\n if (file) {\n vars = vars.filter((v) => v.file_path === file || v.file_path.endsWith(file));\n }\n\n if (vars.length === 0) {\n return { content: [{ type: 'text', text: 'No env vars found. Run indexing first or adjust the filter.' }] };\n }\n\n // Group by file\n const grouped: Record<string, { key: string; type: string; format: string | null; comment: string | null }[]> = {};\n for (const v of vars) {\n const arr = grouped[v.file_path] ??= [];\n arr.push({\n key: v.key,\n type: v.value_type,\n format: v.value_format,\n comment: v.comment,\n });\n }\n\n return { content: [{ type: 'text', text: j(grouped) }] };\n },\n );\n\n // --- Level 1 Navigation Tools ---\n\n server.tool(\n 'get_symbol',\n 'Look up a symbol by symbol_id or FQN and return its source code',\n {\n symbol_id: z.string().max(512).optional().describe('The symbol_id to look up'),\n fqn: z.string().max(512).optional().describe('The fully qualified name to look up'),\n max_lines: z.number().int().min(1).max(10000).optional().describe('Truncate source to this many lines (omit for full source)'),\n },\n async ({ symbol_id, fqn, max_lines }) => {\n const result = getSymbol(store, projectRoot, { symbolId: symbol_id, fqn, maxLines: max_lines });\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n const { symbol, file, source, truncated } = result.value;\n return {\n content: [{\n type: 'text',\n text: j({\n symbol_id: symbol.symbol_id,\n name: symbol.name,\n kind: symbol.kind,\n fqn: symbol.fqn,\n signature: symbol.signature,\n summary: symbol.summary,\n file: file.path,\n line_start: symbol.line_start,\n line_end: symbol.line_end,\n source,\n ...(truncated ? { truncated: true } : {}),\n }),\n }],\n };\n },\n );\n\n server.tool(\n 'search',\n 'Search symbols using full-text search with optional filters',\n {\n query: z.string().min(1).max(500).describe('Search query'),\n kind: z.string().max(64).optional().describe('Filter by symbol kind (class, method, function, etc.)'),\n language: z.string().max(64).optional().describe('Filter by language'),\n file_pattern: z.string().max(512).optional().describe('Filter by file path pattern'),\n implements: z.string().max(256).optional().describe('Filter to classes implementing this interface'),\n extends: z.string().max(256).optional().describe('Filter to classes/interfaces extending this name'),\n limit: z.number().int().min(1).max(500).optional().describe('Max results (default 20)'),\n offset: z.number().int().min(0).max(50000).optional().describe('Offset for pagination'),\n },\n async ({ query, kind, language, file_pattern, limit, offset, implements: impl, extends: ext }) => {\n const result = await search(\n store,\n query,\n { kind, language, filePattern: file_pattern, implements: impl, extends: ext },\n limit ?? 20,\n offset ?? 0,\n { vectorStore, embeddingService, reranker },\n );\n // Project to AI-useful fields only — strips DB internals (id, file_id, byte offsets, etc.)\n const items: SearchResultItemProjected[] = result.items.map(({ symbol, file, score }) => ({\n symbol_id: symbol.symbol_id,\n name: symbol.name,\n kind: symbol.kind,\n fqn: symbol.fqn,\n signature: symbol.signature,\n summary: symbol.summary,\n file: file.path,\n line: symbol.line_start,\n score,\n }));\n return { content: [{ type: 'text', text: j({ items, total: result.total, search_mode: result.search_mode }) }] };\n },\n );\n\n server.tool(\n 'get_file_outline',\n 'Get all symbols for a file (signatures only, no bodies)',\n {\n path: z.string().max(512).describe('Relative file path'),\n },\n async ({ path: filePath }) => {\n const blocked = guardPath(filePath);\n if (blocked) return blocked;\n const result = getFileOutline(store, filePath);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n\n server.tool(\n 'get_change_impact',\n 'Determine what depends on a file or symbol (reverse dependency analysis)',\n {\n file_path: z.string().max(512).optional().describe('Relative file path to analyze'),\n symbol_id: z.string().max(512).optional().describe('Symbol ID to analyze'),\n depth: z.number().int().min(1).max(20).optional().describe('Max traversal depth (default 3)'),\n max_dependents: z.number().int().min(1).max(5000).optional().describe('Cap on returned dependents (default 200)'),\n },\n async ({ file_path, symbol_id, depth, max_dependents }) => {\n if (file_path) {\n const blocked = guardPath(file_path);\n if (blocked) return blocked;\n }\n const result = getChangeImpact(\n store,\n { filePath: file_path, symbolId: symbol_id },\n depth ?? 3,\n max_dependents ?? 200,\n );\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n\n server.tool(\n 'get_feature_context',\n 'Find relevant symbols and code for a feature description using FTS + graph expansion',\n {\n description: z.string().min(1).max(2000).describe('Natural language description of the feature to find context for'),\n token_budget: z.number().int().min(100).max(100000).optional().describe('Max tokens for assembled context (default 4000)'),\n },\n async ({ description, token_budget }) => {\n const result = getFeatureContext(store, projectRoot, description, token_budget ?? 4000);\n return { content: [{ type: 'text', text: j(result) }] };\n },\n );\n\n // --- Level 2 Framework Tools ---\n\n if (has('vue', 'nuxt', 'inertia')) {\n server.tool(\n 'get_component_tree',\n 'Build a component render tree starting from a given .vue file',\n {\n component_path: z.string().max(512).describe('Relative path to the root .vue file'),\n depth: z.number().int().min(1).max(20).optional().describe('Max tree depth (default 3)'),\n token_budget: z.number().int().min(100).max(100000).optional().describe('Max tokens for the tree (default 8000)'),\n },\n async ({ component_path, depth, token_budget }) => {\n const blocked = guardPath(component_path);\n if (blocked) return blocked;\n const result = getComponentTree(store, component_path, depth ?? 3, token_budget ?? 8000);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n }\n\n // --- Level 3 Framework-Specific Tools ---\n\n if (has('express', 'nestjs', 'laravel', 'fastapi', 'flask', 'drf', 'spring', 'rails', 'fastify', 'hono', 'trpc')) {\n server.tool(\n 'get_request_flow',\n 'Trace request flow for a URL+method: route → middleware → controller → service (Laravel/Express/NestJS/Fastify/Hono/tRPC/FastAPI/Flask/DRF)',\n {\n url: z.string().max(512).describe('Route URL (e.g. /api/users)'),\n method: z.string().max(64).optional().describe('HTTP method (default GET)'),\n },\n async ({ url, method }) => {\n const result = getRequestFlow(store, url, method ?? 'GET');\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n }\n\n if (has('express', 'nestjs', 'fastapi', 'flask', 'spring')) {\n server.tool(\n 'get_middleware_chain',\n 'Trace middleware chain for a route URL (Express/NestJS/FastAPI/Flask)',\n {\n url: z.string().max(512).describe('Route URL to trace middleware for'),\n },\n async ({ url }) => {\n const result = getMiddlewareChain(store, projectRoot, url);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n }\n\n if (has('nestjs')) {\n server.tool(\n 'get_module_graph',\n 'Build NestJS module dependency graph (module -> imports -> controllers -> providers -> exports)',\n {\n module_name: z.string().max(256).describe('NestJS module class name (e.g. AppModule)'),\n },\n async ({ module_name }) => {\n const result = getModuleGraph(store, projectRoot, module_name);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n\n server.tool(\n 'get_di_tree',\n 'Trace NestJS dependency injection tree (what a service injects + who injects it)',\n {\n service_name: z.string().max(256).describe('NestJS service/provider class name'),\n },\n async ({ service_name }) => {\n const result = getDITree(store, service_name);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n }\n\n if (has('react-native')) {\n server.tool(\n 'get_navigation_graph',\n 'Build React Native navigation tree from screens, navigators, and deep links',\n {},\n async () => {\n const result = getNavigationGraph(store);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n\n server.tool(\n 'get_screen_context',\n 'Get full context for a React Native screen: navigator, navigation edges, deep link, platform variants, native modules',\n {\n screen_name: z.string().max(256).describe('Screen name (e.g. ProfileScreen or Profile)'),\n },\n async ({ screen_name }) => {\n const result = getScreenContext(store, screen_name);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n }\n\n if (has('laravel', 'mongoose', 'sequelize', 'prisma', 'typeorm', 'drizzle', 'sqlalchemy')) {\n server.tool(\n 'get_model_context',\n 'Get full model context: relationships, schema, and metadata (Eloquent/Mongoose/Sequelize/SQLAlchemy/Prisma/TypeORM/Drizzle)',\n {\n model_name: z.string().max(256).describe('Model class name (e.g. User, Post)'),\n },\n async ({ model_name }) => {\n const result = getModelContext(store, model_name);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n\n server.tool(\n 'get_schema',\n 'Get database schema reconstructed from migrations or ORM model definitions',\n {\n table_name: z.string().max(256).optional().describe('Table/collection/model name (omit for all)'),\n },\n async ({ table_name }) => {\n const result = getSchema(store, table_name);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n }\n\n if (has('laravel', 'nestjs', 'celery', 'django', 'socketio')) {\n server.tool(\n 'get_event_graph',\n 'Get event/signal/task dispatch graph (Laravel events, Django signals, NestJS events, Celery tasks, Socket.io events)',\n {\n event_name: z.string().max(256).optional().describe('Filter to a specific event class name'),\n },\n async ({ event_name }) => {\n const result = getEventGraph(store, event_name);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n }\n\n server.tool(\n 'find_references',\n 'Find all places that reference a symbol or file (incoming edges: imports, calls, renders, dispatches, etc.)',\n {\n symbol_id: z.string().max(512).optional().describe('Symbol ID to find references for'),\n fqn: z.string().max(512).optional().describe('Fully qualified name to find references for'),\n file_path: z.string().max(512).optional().describe('File path to find references for'),\n },\n async ({ symbol_id, fqn, file_path }) => {\n if (file_path) {\n const blocked = guardPath(file_path);\n if (blocked) return blocked;\n }\n const result = findReferences(store, { symbolId: symbol_id, fqn, filePath: file_path });\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n\n server.tool(\n 'get_call_graph',\n 'Build a bidirectional call graph centered on a symbol (who it calls + who calls it)',\n {\n symbol_id: z.string().max(512).optional().describe('Symbol ID to center the graph on'),\n fqn: z.string().max(512).optional().describe('Fully qualified name to center the graph on'),\n depth: z.number().int().min(1).max(20).optional().describe('Traversal depth on each side (default 2)'),\n },\n async ({ symbol_id, fqn, depth }) => {\n const result = getCallGraph(store, { symbolId: symbol_id, fqn }, depth ?? 2);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n\n server.tool(\n 'get_tests_for',\n 'Find test files and test functions that cover a given symbol or file',\n {\n symbol_id: z.string().max(512).optional().describe('Symbol ID to find tests for'),\n fqn: z.string().max(512).optional().describe('Fully qualified name to find tests for'),\n file_path: z.string().max(512).optional().describe('File path to find tests for'),\n },\n async ({ symbol_id, fqn, file_path }) => {\n if (file_path) {\n const blocked = guardPath(file_path);\n if (blocked) return blocked;\n }\n const result = getTestsFor(store, { symbolId: symbol_id, fqn, filePath: file_path });\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n\n if (has('laravel')) {\n server.tool(\n 'get_livewire_context',\n 'Get full context for a Livewire component: properties, actions, events, view, child components',\n {\n component_name: z.string().max(256).describe('Livewire component class name or FQN (e.g. UserProfile or App\\\\Livewire\\\\UserProfile)'),\n },\n async ({ component_name }) => {\n const result = getLivewireContext(store, component_name);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n\n server.tool(\n 'get_nova_resource',\n 'Get full context for a Laravel Nova resource: model, fields, actions, filters, lenses, metrics',\n {\n resource_name: z.string().max(256).describe('Nova resource class name or FQN (e.g. User or App\\\\Nova\\\\User)'),\n },\n async ({ resource_name }) => {\n const result = getNovaResource(store, resource_name);\n if (result.isErr()) {\n return { content: [{ type: 'text', text: j(formatToolError(result.error)) }], isError: true };\n }\n return { content: [{ type: 'text', text: j(result.value) }] };\n },\n );\n }\n\n if (has('zustand-redux')) {\n server.tool(\n 'get_state_stores',\n 'List all Zustand stores and Redux Toolkit slices with their state fields, actions/reducers, and dispatch sites',\n {},\n async () => {\n const routes = store.getAllRoutes();\n const stores = routes.filter((r) => r.method === 'STORE' || r.method === 'SLICE');\n const dispatches = routes.filter((r) => r.method === 'DISPATCH');\n return {\n content: [{\n type: 'text',\n text: j({\n stores: stores.map((s) => ({\n type: s.method === 'STORE' ? 'zustand' : 'redux',\n name: s.uri.replace(/^(zustand|redux):/, ''),\n handler: s.handler,\n metadata: s.metadata ? JSON.parse(s.metadata) : null,\n })),\n dispatches: dispatches.map((d) => ({\n action: d.uri.replace(/^action:/, ''),\n file: d.file_id ? store.getFileById(d.file_id)?.path : null,\n })),\n totalStores: stores.length,\n totalDispatches: dispatches.length,\n }),\n }],\n };\n },\n );\n }\n\n // --- Self-Development / Introspection Tools ---\n\n server.tool(\n 'get_implementations',\n 'Find all classes that implement or extend a given interface or base class',\n {\n name: z.string().max(256).describe('Interface or base class name (e.g. UserRepositoryInterface)'),\n },\n async ({ name }) => {\n const result = getImplementations(store, name);\n return { content: [{ type: 'text', text: j(result) }] };\n },\n );\n\n server.tool(\n 'get_api_surface',\n 'List all exported symbols (public API) of a file or matching files',\n {\n file_pattern: z.string().max(512).optional().describe('Glob-style pattern to filter files (e.g. src/services/*.ts)'),\n },\n async ({ file_pattern }) => {\n const result = getApiSurface(store, file_pattern);\n return { content: [{ type: 'text', text: j(result) }] };\n },\n );\n\n server.tool(\n 'get_plugin_registry',\n 'List all registered indexer plugins and the edge types they emit',\n {},\n async () => {\n const result = getPluginRegistry(store, registry, frameworkNames);\n return { content: [{ type: 'text', text: j(result) }] };\n },\n );\n\n server.tool(\n 'get_type_hierarchy',\n 'Walk TypeScript class/interface hierarchy: ancestors (what it extends/implements) and descendants (what extends/implements it)',\n {\n name: z.string().max(256).describe('Class or interface name (e.g. \"LanguagePlugin\", \"Store\")'),\n max_depth: z.number().int().min(1).max(20).optional().describe('Max traversal depth (default 10)'),\n },\n async ({ name, max_depth }) => {\n const result = getTypeHierarchy(store, name, max_depth ?? 10);\n return { content: [{ type: 'text', text: j(result) }] };\n },\n );\n\n server.tool(\n 'get_dead_exports',\n 'Find exported symbols never imported by any other file — dead code candidates',\n {\n file_pattern: z.string().max(512).optional().describe('Filter files by glob pattern (e.g. \"src/tools/*.ts\")'),\n },\n async ({ file_pattern }) => {\n const result = getDeadExports(store, file_pattern);\n return { content: [{ type: 'text', text: j(result) }] };\n },\n );\n\n server.tool(\n 'get_dependency_graph',\n 'Show file-level dependency graph: what a file imports and what imports it (requires reindex for ESM edge resolution)',\n {\n file_path: z.string().max(512).describe('Relative file path to analyze (e.g. \"src/server.ts\")'),\n },\n async ({ file_path }) => {\n const blocked = guardPath(file_path);\n if (blocked) return blocked;\n const result = getDependencyGraph(store, file_path);\n return { content: [{ type: 'text', text: j(result) }] };\n },\n );\n\n server.tool(\n 'get_untested_exports',\n 'Find exported public symbols with no matching test file — test coverage gaps',\n {\n file_pattern: z.string().max(512).optional().describe('Filter by file glob pattern (e.g. \"src/tools/%\")'),\n },\n async ({ file_pattern }) => {\n const result = getUntestedExports(store, file_pattern);\n return { content: [{ type: 'text', text: j(result) }] };\n },\n );\n\n\n server.tool('self_audit', 'One-shot project health audit: dead exports, untested code, dependency hotspots, heritage metrics', {}, async () => {\n return { content: [{ type: 'text', text: j(selfAudit(store)) }] };\n });\n // --- Resources ---\n\n server.resource(\n 'project-map',\n 'project://map',\n { mimeType: 'application/json', description: 'Project map (frameworks, stats, structure)' },\n async () => {\n const result = getProjectMap(store, registry);\n return {\n contents: [{ uri: 'project://map', mimeType: 'application/json', text: j(result) }],\n };\n },\n );\n\n server.resource(\n 'project-health',\n 'project://health',\n { mimeType: 'application/json', description: 'Index health status' },\n async () => {\n const result = getIndexHealth(store, config);\n return {\n contents: [{ uri: 'project://health', mimeType: 'application/json', text: j(result) }],\n };\n },\n );\n\n // --- AI-powered tools (registered only when AI is enabled) ---\n if (config.ai?.enabled) {\n registerAITools(server, {\n store,\n smartInference: aiProvider.inference(),\n fastInference: aiProvider.fastInference(),\n embeddingService,\n vectorStore,\n reranker,\n projectRoot,\n });\n }\n\n return server;\n}\n","import type { Store, IndexStats } from '../db/store.js';\nimport type { PluginRegistry } from '../plugin-api/registry.js';\nimport type { TraceMcpConfig } from '../config.js';\n\nexport interface IndexHealthResult {\n status: 'ok' | 'degraded' | 'empty';\n stats: IndexStats;\n schemaVersion: number;\n config: {\n dbPath: string;\n includePatterns: string[];\n excludePatterns: string[];\n };\n warnings: string[];\n}\n\nexport function getIndexHealth(\n store: Store,\n config: TraceMcpConfig,\n): IndexHealthResult {\n const stats = store.getStats();\n const warnings: string[] = [];\n\n let status: 'ok' | 'degraded' | 'empty' = 'ok';\n if (stats.totalFiles === 0) {\n status = 'empty';\n } else if (stats.partialFiles > 0 || stats.errorFiles > 0) {\n status = 'degraded';\n if (stats.partialFiles > 0) warnings.push(`${stats.partialFiles} files parsed partially`);\n if (stats.errorFiles > 0) warnings.push(`${stats.errorFiles} files failed to parse`);\n }\n\n const versionRow = store.db.prepare(\"SELECT value FROM schema_meta WHERE key = 'schema_version'\").get() as { value: string } | undefined;\n\n return {\n status,\n stats,\n schemaVersion: versionRow ? Number(versionRow.value) : 0,\n config: {\n dbPath: config.db.path,\n includePatterns: config.include,\n excludePatterns: config.exclude,\n },\n warnings,\n };\n}\n\nexport interface ProjectMapResult {\n frameworks: string[];\n stats: IndexStats;\n languages: { language: string; count: number }[];\n}\n\nexport interface ProjectMapSummary {\n frameworks: string[];\n fileCount: number;\n symbolCount: number;\n languages: string[];\n}\n\nexport function getProjectMap(store: Store, registry: PluginRegistry, summaryOnly?: boolean): ProjectMapResult | ProjectMapSummary {\n const stats = store.getStats();\n const frameworks = registry.getAllFrameworkPlugins().map((p) => p.manifest.name);\n\n if (summaryOnly) {\n const languageRows = store.db.prepare(\n 'SELECT language FROM files WHERE language IS NOT NULL GROUP BY language ORDER BY COUNT(*) DESC',\n ).all() as { language: string }[];\n return {\n frameworks,\n fileCount: stats.totalFiles,\n symbolCount: stats.totalSymbols,\n languages: languageRows.map((r) => r.language),\n };\n }\n\n const languageRows = store.db.prepare(\n 'SELECT language, COUNT(*) as count FROM files WHERE language IS NOT NULL GROUP BY language ORDER BY count DESC',\n ).all() as { language: string; count: number }[];\n\n return {\n frameworks,\n stats,\n languages: languageRows,\n };\n}\n","import path from 'node:path';\nimport type { Store, SymbolRow, FileRow } from '../db/store.js';\nimport { searchFts, type FtsResult, type FtsFilters } from '../db/fts.js';\nimport { readByteRange } from '../utils/source-reader.js';\nimport { hybridScore, getTypeBonus, computeRecency } from '../scoring/hybrid.js';\nimport { computePageRank } from '../scoring/pagerank.js';\nimport { notFound, type TraceMcpResult } from '../errors.js';\nimport { ok, err } from 'neverthrow';\nimport { hybridSearch as aiHybridSearch } from '../ai/search.js';\nimport type { VectorStore, EmbeddingService, RerankerService } from '../ai/interfaces.js';\n\n// ─── get_symbol ─────────────────────────────────────────────\n\nexport interface GetSymbolResult {\n symbol: SymbolRow;\n file: FileRow;\n source: string;\n truncated?: boolean;\n}\n\nexport function getSymbol(\n store: Store,\n rootPath: string,\n opts: { symbolId?: string; fqn?: string; maxLines?: number },\n): TraceMcpResult<GetSymbolResult> {\n let symbol: SymbolRow | undefined;\n\n if (opts.symbolId) {\n symbol = store.getSymbolBySymbolId(opts.symbolId);\n } else if (opts.fqn) {\n symbol = store.getSymbolByFqn(opts.fqn);\n }\n\n if (!symbol) {\n return err(notFound(opts.symbolId ?? opts.fqn ?? 'unknown'));\n }\n\n const file = store.getFileById(symbol.file_id);\n if (!file) {\n return err(notFound(`file:${symbol.file_id}`));\n }\n\n const absPath = path.resolve(rootPath, file.path);\n let source: string;\n let truncated: boolean | undefined;\n try {\n source = readByteRange(absPath, symbol.byte_start, symbol.byte_end);\n if (opts.maxLines != null) {\n const lines = source.split('\\n');\n if (lines.length > opts.maxLines) {\n source = lines.slice(0, opts.maxLines).join('\\n') + '\\n// ... truncated';\n truncated = true;\n }\n }\n } catch {\n source = symbol.signature ?? '// source unavailable';\n }\n\n return ok({ symbol, file, source, ...(truncated ? { truncated: true } : {}) });\n}\n\n// ─── search ─────────────────────────────────────────────────\n\nexport interface SearchFilters {\n kind?: string;\n language?: string;\n filePattern?: string;\n /** Filter to symbols that implement this interface (metadata.implements contains value) */\n implements?: string;\n /** Filter to symbols that extend this class/interface (metadata.extends contains value) */\n extends?: string;\n}\n\nexport interface SearchResultItem {\n symbol: SymbolRow;\n file: FileRow;\n score: number;\n}\n\n/** Projected search item: only fields useful to an AI client */\nexport interface SearchResultItemProjected {\n symbol_id: string;\n name: string;\n kind: string;\n fqn: string | null;\n signature: string | null;\n summary: string | null;\n file: string;\n line: number | null;\n score: number;\n}\n\nexport interface SearchAIOptions {\n vectorStore?: VectorStore | null;\n embeddingService?: EmbeddingService | null;\n reranker?: RerankerService | null;\n}\n\nexport interface SearchResult {\n items: SearchResultItem[];\n total: number;\n search_mode?: 'hybrid_ai' | 'fts';\n}\n\nexport async function search(\n store: Store,\n query: string,\n filters?: SearchFilters,\n limit = 20,\n offset = 0,\n aiOptions?: SearchAIOptions,\n): Promise<SearchResult> {\n const fetchLimit = limit + offset + 50;\n const useAI = !!(aiOptions?.vectorStore && aiOptions?.embeddingService);\n\n // Build initial candidates: (symbolIdStr, relevance [0,1])\n let candidates: Array<{ symbolIdStr: string; relevance: number }>;\n let searchMode: 'hybrid_ai' | 'fts';\n\n if (useAI) {\n const hybridResults = await aiHybridSearch(\n store.db,\n query,\n aiOptions!.vectorStore!,\n aiOptions!.embeddingService!,\n fetchLimit,\n aiOptions?.reranker,\n );\n if (hybridResults.length === 0) return { items: [], total: 0, search_mode: 'hybrid_ai' };\n // Normalize RRF scores (already positive, descending)\n const maxScore = hybridResults[0].score || 1;\n candidates = hybridResults.map((r) => ({\n symbolIdStr: r.symbolIdStr,\n relevance: r.score / maxScore,\n }));\n searchMode = 'hybrid_ai';\n } else {\n const ftsFilters: FtsFilters = {\n kind: filters?.kind,\n language: filters?.language,\n filePattern: filters?.filePattern,\n };\n const ftsResults = searchFts(store.db, query, fetchLimit, 0, ftsFilters);\n if (ftsResults.length === 0) return { items: [], total: 0, search_mode: 'fts' };\n // BM25 ranks are negative: lower = better match\n const minRank = Math.min(...ftsResults.map((r) => r.rank));\n const maxRank = Math.max(...ftsResults.map((r) => r.rank));\n const rankSpread = maxRank - minRank || 1;\n candidates = ftsResults.map((r) => ({\n symbolIdStr: r.symbolIdStr,\n relevance: 1 - (r.rank - minRank) / rankSpread,\n }));\n searchMode = 'fts';\n }\n\n // Build PageRank map\n const pagerankMap = computePageRank(store.db);\n const maxPr = Math.max(...pagerankMap.values(), 0.001);\n const now = new Date();\n const scored: SearchResultItem[] = [];\n\n // Batch-fetch all candidate symbols in one query\n const symbolIdStrs = candidates.map((c) => c.symbolIdStr);\n const allSymbols = symbolIdStrs.length > 0\n ? store.db.prepare(\n `SELECT * FROM symbols WHERE symbol_id IN (${symbolIdStrs.map(() => '?').join(',')})`,\n ).all(...symbolIdStrs) as import('../db/store.js').SymbolRow[]\n : [];\n const symbolByIdStr = new Map(allSymbols.map((s) => [s.symbol_id, s]));\n\n // Batch-fetch files and node IDs\n const fileIds = [...new Set(allSymbols.map((s) => s.file_id))];\n const fileMap = store.getFilesByIds(fileIds);\n const symIds = allSymbols.map((s) => s.id);\n const nodeMap = store.getNodeIdsBatch('symbol', symIds);\n\n // Heritage post-filter: implements / extends (checks symbol metadata)\n const heritageFilter = filters?.implements || filters?.extends;\n\n for (const candidate of candidates) {\n const symbol = symbolByIdStr.get(candidate.symbolIdStr);\n if (!symbol) continue;\n\n if (heritageFilter && symbol.metadata) {\n const meta = typeof symbol.metadata === 'string'\n ? JSON.parse(symbol.metadata) as Record<string, unknown>\n : symbol.metadata as Record<string, unknown>;\n\n if (filters?.implements) {\n const impl = meta['implements'];\n if (!Array.isArray(impl) || !(impl as string[]).includes(filters.implements)) continue;\n }\n if (filters?.extends) {\n const ext = meta['extends'];\n const extArr = Array.isArray(ext) ? ext as string[] : typeof ext === 'string' ? [ext] : [];\n if (!extArr.includes(filters.extends)) continue;\n }\n } else if (heritageFilter) {\n continue; // no metadata → can't match heritage filter\n }\n\n const file = fileMap.get(symbol.file_id);\n if (!file) continue;\n\n const nodeId = nodeMap.get(symbol.id);\n const pr = nodeId ? (pagerankMap.get(nodeId) ?? 0) / maxPr : 0;\n const recency = computeRecency(file.indexed_at, now);\n const typeBonus = getTypeBonus(symbol.kind);\n\n const score = hybridScore({ relevance: candidate.relevance, pagerank: pr, recency, typeBonus });\n scored.push({ symbol, file, score });\n }\n\n scored.sort((a, b) => b.score - a.score);\n const total = scored.length;\n const items = scored.slice(offset, offset + limit);\n\n return { items, total, search_mode: searchMode };\n}\n\n// ─── get_file_outline ───────────────────────────────────────\n\nexport interface FileOutlineSymbol {\n symbolId: string;\n name: string;\n kind: string;\n fqn: string | null;\n signature: string | null;\n lineStart: number | null;\n lineEnd: number | null;\n}\n\nexport interface FileOutlineResult {\n path: string;\n language: string | null;\n symbols: FileOutlineSymbol[];\n}\n\nexport function getFileOutline(\n store: Store,\n filePath: string,\n): TraceMcpResult<FileOutlineResult> {\n const file = store.getFile(filePath);\n if (!file) {\n return err(notFound(filePath));\n }\n\n const symbols = store.getSymbolsByFile(file.id);\n\n return ok({\n path: file.path,\n language: file.language,\n symbols: symbols.map((s) => ({\n symbolId: s.symbol_id,\n name: s.name,\n kind: s.kind,\n fqn: s.fqn,\n signature: s.signature,\n lineStart: s.line_start,\n lineEnd: s.line_end,\n })),\n });\n}\n","import type Database from 'better-sqlite3';\n\nexport interface FtsResult {\n symbolId: number;\n rank: number;\n name: string;\n fqn: string | null;\n kind: string;\n fileId: number;\n symbolIdStr: string;\n}\n\nexport interface FtsFilters {\n kind?: string;\n language?: string;\n filePattern?: string;\n}\n\nexport function searchFts(\n db: Database.Database,\n query: string,\n limit = 20,\n offset = 0,\n filters?: FtsFilters,\n): FtsResult[] {\n // Escape FTS5 special characters\n const escaped = escapeFtsQuery(query);\n if (!escaped) return [];\n\n const conditions: string[] = ['symbols_fts MATCH ?'];\n const params: unknown[] = [escaped];\n\n // Push filters into SQL to avoid fetching excess rows\n if (filters?.kind) {\n conditions.push('s.kind = ?');\n params.push(filters.kind);\n }\n if (filters?.language) {\n conditions.push('f.language = ?');\n params.push(filters.language);\n }\n if (filters?.filePattern) {\n conditions.push('f.path LIKE ?');\n params.push(`%${filters.filePattern}%`);\n }\n\n const needsFileJoin = filters?.language || filters?.filePattern;\n const fileJoin = needsFileJoin ? 'JOIN files f ON f.id = s.file_id' : '';\n\n const sql = `\n SELECT\n s.id as symbolId,\n rank as rank,\n s.name,\n s.fqn,\n s.kind,\n s.file_id as fileId,\n s.symbol_id as symbolIdStr\n FROM symbols_fts fts\n JOIN symbols s ON s.id = fts.rowid\n ${fileJoin}\n WHERE ${conditions.join(' AND ')}\n ORDER BY rank\n LIMIT ? OFFSET ?\n `;\n\n params.push(limit, offset);\n return db.prepare(sql).all(...params) as FtsResult[];\n}\n\nexport function escapeFtsQuery(query: string): string {\n // Remove special FTS5 characters, then strip boolean keywords that survive as whole words\n const cleaned = query\n .replace(/['\"(){}[\\]*:^~!@#$%&]/g, ' ')\n .replace(/\\b(OR|AND|NOT)\\b/gi, ' ')\n .trim();\n if (!cleaned) return '';\n\n // Split into terms and wrap each in quotes for exact phrase matching\n const terms = cleaned.split(/\\s+/).filter(Boolean);\n return terms.map((t) => `\"${t}\"`).join(' ');\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { redactEnvFile } from './env-parser.js';\n\n/**\n * Read source code from a file using byte offsets. O(1) retrieval.\n */\nexport function readByteRange(\n filePath: string,\n byteStart: number,\n byteEnd: number,\n): string {\n if (byteEnd <= byteStart || byteStart < 0) return '';\n const fd = fs.openSync(filePath, 'r');\n try {\n const length = byteEnd - byteStart;\n const buffer = Buffer.alloc(length);\n const bytesRead = fs.readSync(fd, buffer, 0, length, byteStart);\n return buffer.subarray(0, bytesRead).toString('utf8');\n } finally {\n fs.closeSync(fd);\n }\n}\n\nconst ENV_BASENAME_RE = /^\\.env(\\..+)?$/;\n\n/** Check if a file path is a .env file. */\nexport function isEnvFile(filePath: string): boolean {\n return ENV_BASENAME_RE.test(path.basename(filePath));\n}\n\n/**\n * Read a file safely — if it's a .env file, redact values and return only\n * keys with type hints. For all other files, return content as-is.\n */\nexport function readFileSafe(filePath: string): string {\n const content = fs.readFileSync(filePath, 'utf-8');\n if (isEnvFile(filePath)) {\n return redactEnvFile(content);\n }\n return content;\n}\n","/**\n * Parses .env files and extracts keys with inferred value types/formats.\n * Never exposes actual values — only structural metadata.\n */\n\nexport type EnvValueType = 'string' | 'number' | 'boolean' | 'empty';\n\nexport type EnvValueFormat =\n | 'url'\n | 'email'\n | 'ip'\n | 'host:port'\n | 'path'\n | 'uuid'\n | 'json'\n | 'base64'\n | 'csv'\n | 'integer'\n | 'float'\n | 'cron'\n | 'duration'\n | 'semver'\n | 'hex'\n | 'dsn'\n | null;\n\nexport interface EnvEntry {\n key: string;\n valueType: EnvValueType;\n valueFormat: EnvValueFormat;\n comment: string | null;\n /** Whether the value was wrapped in quotes */\n quoted: boolean;\n line: number;\n}\n\n// ─── Format detectors (order matters: most specific first) ───────────\n\nconst FORMAT_DETECTORS: Array<{ format: EnvValueFormat; test: (v: string) => boolean }> = [\n // UUID: 8-4-4-4-12 hex digits\n { format: 'uuid', test: (v) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v) },\n // URL: scheme://...\n { format: 'url', test: (v) => /^https?:\\/\\/.+/i.test(v) || /^(redis|amqp|mqtt|ftp|ftps|ssh|wss?|mongodb(\\+srv)?|postgres(ql)?|mysql|sqlite):\\/\\/.+/i.test(v) },\n // DSN: scheme://user:pass@host or scheme://host — covers DB connection strings not caught by URL\n { format: 'dsn', test: (v) => /^[a-z][a-z0-9+.-]*:\\/\\/.+/i.test(v) },\n // Email\n { format: 'email', test: (v) => /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(v) },\n // Semver: 1.2.3 or v1.2.3 with optional pre-release\n { format: 'semver', test: (v) => /^v?\\d+\\.\\d+\\.\\d+(-[\\w.]+)?(\\+[\\w.]+)?$/.test(v) },\n // IP v4\n { format: 'ip', test: (v) => /^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(v) },\n // host:port (after IP check to not conflict)\n { format: 'host:port', test: (v) => /^[\\w.-]+:\\d{1,5}$/.test(v) },\n // Cron expression (5 or 6 fields)\n { format: 'cron', test: (v) => /^(\\S+\\s+){4,5}\\S+$/.test(v) && /[*\\/,\\-]/.test(v) },\n // JSON object or array\n { format: 'json', test: (v) => (v.startsWith('{') && v.endsWith('}')) || (v.startsWith('[') && v.endsWith(']')) },\n // CSV: contains commas (and not JSON)\n { format: 'csv', test: (v) => v.includes(',') && !v.startsWith('{') && !v.startsWith('[') },\n // Duration: 30s, 5m, 2h, 1d, 500ms\n { format: 'duration', test: (v) => /^\\d+(ms|s|m|h|d)$/i.test(v) },\n // Hex string (at least 8 chars to avoid matching short words)\n { format: 'hex', test: (v) => /^(0x)?[0-9a-f]{8,}$/i.test(v) && !/^\\d+$/.test(v) },\n // Base64: long alphanumeric with padding or mixed case + digits (at least 16 chars)\n { format: 'base64', test: (v) => v.length >= 16 && /^[A-Za-z0-9+/]+=*$/.test(v) && /[A-Z]/.test(v) && /[a-z]/.test(v) },\n // Absolute path (unix or windows)\n { format: 'path', test: (v) => /^(\\/[\\w.-]+)+\\/?$/.test(v) || /^[A-Z]:\\\\/.test(v) },\n];\n\nfunction inferType(value: string): { valueType: EnvValueType; valueFormat: EnvValueFormat } {\n if (value === '') return { valueType: 'empty', valueFormat: null };\n\n // Boolean\n if (/^(true|false|yes|no|on|off|1|0)$/i.test(value)) {\n return { valueType: 'boolean', valueFormat: null };\n }\n\n // Integer\n if (/^-?\\d+$/.test(value)) {\n return { valueType: 'number', valueFormat: 'integer' };\n }\n\n // Float\n if (/^-?\\d+\\.\\d+$/.test(value)) {\n return { valueType: 'number', valueFormat: 'float' };\n }\n\n // String with format detection\n for (const { format, test } of FORMAT_DETECTORS) {\n if (test(value)) {\n return { valueType: 'string', valueFormat: format };\n }\n }\n\n return { valueType: 'string', valueFormat: null };\n}\n\n/**\n * Strip surrounding quotes from a value and return whether it was quoted.\n */\nfunction unquote(raw: string): { value: string; quoted: boolean } {\n if (\n (raw.startsWith('\"') && raw.endsWith('\"')) ||\n (raw.startsWith(\"'\") && raw.endsWith(\"'\"))\n ) {\n return { value: raw.slice(1, -1), quoted: true };\n }\n return { value: raw, quoted: false };\n}\n\n/**\n * Parse a .env file content and return structured entries without actual values.\n */\nexport function parseEnvFile(content: string): EnvEntry[] {\n const entries: EnvEntry[] = [];\n const lines = content.split('\\n');\n let pendingComment: string | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // Blank line resets pending comment\n if (line === '') {\n pendingComment = null;\n continue;\n }\n\n // Comment line — accumulate for next variable\n if (line.startsWith('#')) {\n const commentText = line.slice(1).trim();\n pendingComment = pendingComment ? `${pendingComment} ${commentText}` : commentText;\n continue;\n }\n\n // Variable line: KEY=VALUE or export KEY=VALUE\n const match = line.match(/^(?:export\\s+)?([A-Za-z_][A-Za-z0-9_]*)=(.*)/);\n if (!match) {\n pendingComment = null;\n continue;\n }\n\n const key = match[1];\n const rawValue = match[2].trim();\n\n // Strip inline comment (only for unquoted values)\n let effectiveRaw = rawValue;\n if (!rawValue.startsWith('\"') && !rawValue.startsWith(\"'\")) {\n const commentIdx = rawValue.indexOf(' #');\n if (commentIdx !== -1) {\n effectiveRaw = rawValue.slice(0, commentIdx).trim();\n }\n }\n\n const { value, quoted } = unquote(effectiveRaw);\n const { valueType, valueFormat } = inferType(value);\n\n entries.push({\n key,\n valueType,\n valueFormat,\n comment: pendingComment,\n quoted,\n line: i + 1,\n });\n\n pendingComment = null;\n }\n\n return entries;\n}\n\n/**\n * Redact .env file content: keep keys and comments, replace values with type hints.\n * Used by source-reader to safely expose .env structure without secrets.\n */\nexport function redactEnvFile(content: string): string {\n const entries = parseEnvFile(content);\n const lines = content.split('\\n');\n const result: string[] = [];\n\n const entryByLine = new Map<number, EnvEntry>();\n for (const e of entries) {\n entryByLine.set(e.line, e);\n }\n\n for (let i = 0; i < lines.length; i++) {\n const entry = entryByLine.get(i + 1);\n if (entry) {\n const typeHint = formatTypeHint(entry);\n result.push(`${entry.key}=${typeHint}`);\n } else {\n // Keep comments and blank lines as-is\n result.push(lines[i]);\n }\n }\n\n return result.join('\\n');\n}\n\nfunction formatTypeHint(entry: EnvEntry): string {\n if (entry.valueType === 'empty') return '<empty>';\n if (entry.valueFormat) return `<${entry.valueType}:${entry.valueFormat}>`;\n return `<${entry.valueType}>`;\n}\n","export interface HybridScoreParams {\n /** FTS5 BM25 rank, normalized 0-1 */\n relevance: number;\n /** PageRank score (already normalized 0-1) */\n pagerank: number;\n /** Recency factor 0-1 based on indexed_at */\n recency: number;\n /** Bonus based on symbol kind 0-1 */\n typeBonus: number;\n}\n\n/**\n * Weighted hybrid score combining multiple signals.\n *\n * Weights: relevance 50%, pagerank 25%, recency 15%, typeBonus 10%.\n */\nexport function hybridScore(params: HybridScoreParams): number {\n return (\n 0.50 * params.relevance +\n 0.25 * params.pagerank +\n 0.15 * params.recency +\n 0.10 * params.typeBonus\n );\n}\n\nconst KIND_BONUS: Record<string, number> = {\n class: 1.0,\n interface: 0.9,\n trait: 0.9,\n enum: 0.8,\n function: 0.7,\n method: 0.6,\n type: 0.5,\n constant: 0.4,\n property: 0.3,\n variable: 0.2,\n enum_case: 0.3,\n namespace: 0.1,\n};\n\n/** Get type bonus for a symbol kind. */\nexport function getTypeBonus(kind: string): number {\n return KIND_BONUS[kind] ?? 0.1;\n}\n\n/**\n * Convert an indexed_at timestamp to a 0-1 recency score.\n * Score decays over `maxAgeDays` (default 30).\n */\nexport function computeRecency(\n indexedAt: string,\n now?: Date,\n maxAgeDays = 30,\n): number {\n const d = new Date(indexedAt);\n const ref = now ?? new Date();\n const ageMs = ref.getTime() - d.getTime();\n const ageDays = ageMs / (1000 * 60 * 60 * 24);\n return Math.max(0, 1 - ageDays / maxAgeDays);\n}\n","import type Database from 'better-sqlite3';\n\ninterface EdgeRecord {\n source_node_id: number;\n target_node_id: number;\n}\n\n/** Cached PageRank result keyed by DB filename + edge count */\nlet _cache: { dbName: string; edgeCount: number; result: Map<number, number> } | null = null;\n\n/** Invalidate the cache (call after bulk edge inserts, e.g. reindex) */\nexport function invalidatePageRankCache(): void {\n _cache = null;\n}\n\n/**\n * Simple PageRank on the edges graph.\n * Results are cached and invalidated when the edge count changes.\n */\nexport function computePageRank(\n db: Database.Database,\n iterations = 20,\n dampingFactor = 0.85,\n): Map<number, number> {\n // Fast cache check: if same DB and edge count hasn't changed, reuse\n const dbName = db.name;\n const countRow = db.prepare('SELECT COUNT(*) as cnt FROM edges WHERE resolved = 1').get() as { cnt: number };\n if (_cache && _cache.dbName === dbName && _cache.edgeCount === countRow.cnt) {\n return _cache.result;\n }\n\n const edges = db.prepare(\n 'SELECT source_node_id, target_node_id FROM edges WHERE resolved = 1',\n ).all() as EdgeRecord[];\n\n // Collect all unique node IDs\n const nodeSet = new Set<number>();\n const outgoing = new Map<number, number[]>();\n\n for (const edge of edges) {\n nodeSet.add(edge.source_node_id);\n nodeSet.add(edge.target_node_id);\n\n let targets = outgoing.get(edge.source_node_id);\n if (!targets) {\n targets = [];\n outgoing.set(edge.source_node_id, targets);\n }\n targets.push(edge.target_node_id);\n }\n\n const nodes = Array.from(nodeSet);\n const n = nodes.length;\n if (n === 0) return new Map();\n\n // Initialize scores\n const scores = new Map<number, number>();\n const initialScore = 1 / n;\n for (const nodeId of nodes) {\n scores.set(nodeId, initialScore);\n }\n\n // Iterate\n const base = (1 - dampingFactor) / n;\n\n for (let iter = 0; iter < iterations; iter++) {\n const newScores = new Map<number, number>();\n for (const nodeId of nodes) {\n newScores.set(nodeId, base);\n }\n\n // Accumulate rank mass lost to sink nodes (no outgoing edges) and redistribute\n // evenly across all nodes to conserve total rank mass.\n let sinkMass = 0;\n\n for (const nodeId of nodes) {\n const targets = outgoing.get(nodeId);\n if (!targets || targets.length === 0) {\n sinkMass += (scores.get(nodeId) ?? 0) * dampingFactor;\n continue;\n }\n\n const share = (scores.get(nodeId) ?? 0) * dampingFactor / targets.length;\n for (const target of targets) {\n newScores.set(target, (newScores.get(target) ?? base) + share);\n }\n }\n\n // Distribute sink mass equally to all nodes\n if (sinkMass > 0) {\n const sinkShare = sinkMass / n;\n for (const nodeId of nodes) {\n newScores.set(nodeId, (newScores.get(nodeId) ?? base) + sinkShare);\n }\n }\n\n for (const nodeId of nodes) {\n scores.set(nodeId, newScores.get(nodeId) ?? base);\n }\n }\n\n _cache = { dbName, edgeCount: countRow.cnt, result: scores };\n return scores;\n}\n","/**\n * Hybrid search: combines FTS5 + vector search using Reciprocal Rank Fusion (RRF).\n * Falls back to FTS5-only when AI is unavailable.\n */\nimport type Database from 'better-sqlite3';\nimport { searchFts, type FtsResult } from '../db/fts.js';\nimport type { VectorStore, EmbeddingService, RerankerService } from './interfaces.js';\n\nexport interface HybridSearchResult {\n symbolId: number;\n name: string;\n fqn: string | null;\n kind: string;\n fileId: number;\n symbolIdStr: string;\n score: number;\n}\n\nconst RRF_K = 60;\n\n/**\n * Combine FTS5 + vector search using RRF (Reciprocal Rank Fusion).\n *\n * When vectorStore/embeddingService are null, falls back to FTS5-only.\n */\nexport async function hybridSearch(\n db: Database.Database,\n query: string,\n vectorStore: VectorStore | null,\n embeddingService: EmbeddingService | null,\n limit: number,\n reranker?: RerankerService | null,\n): Promise<HybridSearchResult[]> {\n // 1. FTS5 search\n const ftsResults = searchFts(db, query, limit * 3);\n\n // Build FTS rank map: symbolId -> rank position (0-based)\n const ftsRanked = new Map<number, { rank: number; result: FtsResult }>();\n for (let i = 0; i < ftsResults.length; i++) {\n ftsRanked.set(ftsResults[i].symbolId, { rank: i, result: ftsResults[i] });\n }\n\n // 2. Vector search (if available)\n const vectorRanked = new Map<number, number>();\n\n if (vectorStore && embeddingService) {\n try {\n const queryEmbedding = await embeddingService.embed(query);\n if (queryEmbedding.length > 0) {\n const vectorResults = vectorStore.search(queryEmbedding, limit * 3);\n for (let i = 0; i < vectorResults.length; i++) {\n vectorRanked.set(vectorResults[i].id, i);\n }\n }\n } catch {\n // Vector search failed, continue with FTS-only\n }\n }\n\n // 3. RRF fusion\n const allIds = new Set([...ftsRanked.keys(), ...vectorRanked.keys()]);\n const fused: HybridSearchResult[] = [];\n\n for (const id of allIds) {\n let score = 0;\n\n const ftsEntry = ftsRanked.get(id);\n if (ftsEntry !== undefined) {\n score += 1 / (RRF_K + ftsEntry.rank);\n }\n\n const vecRank = vectorRanked.get(id);\n if (vecRank !== undefined) {\n score += 1 / (RRF_K + vecRank);\n }\n\n // We need name/fqn/kind/fileId — get from FTS if available, else look up\n if (ftsEntry) {\n fused.push({\n symbolId: id,\n name: ftsEntry.result.name,\n fqn: ftsEntry.result.fqn,\n kind: ftsEntry.result.kind,\n fileId: ftsEntry.result.fileId,\n symbolIdStr: ftsEntry.result.symbolIdStr,\n score,\n });\n } else {\n // Symbol only in vector results — look up from DB\n const row = db.prepare(\n 'SELECT id, name, fqn, kind, file_id, symbol_id FROM symbols WHERE id = ?',\n ).get(id) as { id: number; name: string; fqn: string | null; kind: string; file_id: number; symbol_id: string } | undefined;\n\n if (row) {\n fused.push({\n symbolId: id,\n name: row.name,\n fqn: row.fqn,\n kind: row.kind,\n fileId: row.file_id,\n symbolIdStr: row.symbol_id,\n score,\n });\n }\n }\n }\n\n // 4. Sort by RRF score descending\n fused.sort((a, b) => b.score - a.score);\n\n // 5. Optional reranking\n if (reranker && fused.length > 1) {\n try {\n const candidates = fused.slice(0, limit * 2);\n const docs = candidates.map((c) => ({\n id: c.symbolId,\n text: [c.kind, c.fqn ?? c.name, c.name].join(' '),\n }));\n const reranked = await reranker.rerank(query, docs, limit);\n const rerankedIds = new Map(reranked.map((r) => [r.id, r.score]));\n const result: HybridSearchResult[] = [];\n for (const r of reranked) {\n const original = candidates.find((c) => c.symbolId === r.id);\n if (original) {\n result.push({ ...original, score: r.score });\n }\n }\n return result;\n } catch {\n // Reranker failed, fall through to RRF-only results\n }\n }\n\n return fused.slice(0, limit);\n}\n","/**\n * Token estimation: chars/4 * 1.15\n * Trade-off: speed > accuracy, ~15-20% margin.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil((text.length / 4) * 1.15);\n}\n","import type { Store, ComponentRow } from '../db/store.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { notFound } from '../errors.js';\nimport { estimateTokens } from '../utils/token-counter.js';\n\nexport interface ComponentTreeNode {\n name: string;\n path: string;\n props?: string[];\n emits?: string[];\n slots?: string[];\n composables?: string[];\n children: ComponentTreeNode[];\n}\n\nexport interface ComponentTreeResult {\n root: ComponentTreeNode;\n totalComponents: number;\n truncated?: boolean;\n}\n\n/**\n * Build a component tree starting from a given file path.\n *\n * Resolves child components via renders_component edges in the graph,\n * recursing up to `depth` levels.\n */\nexport function getComponentTree(\n store: Store,\n componentPath: string,\n depth = 3,\n tokenBudget = 8000,\n): TraceMcpResult<ComponentTreeResult> {\n const file = store.getFile(componentPath);\n if (!file) {\n return err(notFound(componentPath));\n }\n\n const component = store.getComponentByFileId(file.id);\n if (!component) {\n return err(notFound(componentPath, ['File exists but has no component entry']));\n }\n\n const visited = new Set<string>();\n const budgetRef = { remaining: tokenBudget, truncated: false };\n const root = buildNode(store, component, file.path, depth, visited, budgetRef);\n\n return ok({\n root,\n totalComponents: visited.size,\n ...(budgetRef.truncated ? { truncated: true } : {}),\n });\n}\n\nfunction buildNode(\n store: Store,\n comp: ComponentRow,\n filePath: string,\n remainingDepth: number,\n visited: Set<string>,\n budget: { remaining: number; truncated: boolean },\n): ComponentTreeNode {\n visited.add(filePath);\n\n const node: ComponentTreeNode = {\n name: comp.name,\n path: filePath,\n children: [],\n };\n\n // Parse stored JSON fields (gracefully handle corrupted data)\n try {\n if (comp.props) {\n const parsed = JSON.parse(comp.props) as Record<string, unknown>;\n node.props = Object.keys(parsed);\n }\n } catch { /* corrupted JSON */ }\n try {\n if (comp.emits) node.emits = JSON.parse(comp.emits) as string[];\n } catch { /* corrupted JSON */ }\n try {\n if (comp.slots) node.slots = JSON.parse(comp.slots) as string[];\n } catch { /* corrupted JSON */ }\n try {\n if (comp.composables) node.composables = JSON.parse(comp.composables) as string[];\n } catch { /* corrupted JSON */ }\n\n budget.remaining -= estimateTokens(JSON.stringify(node));\n if (budget.remaining <= 0 || remainingDepth <= 0) return node;\n\n // Find child components via renders_component edges\n const symbols = store.getSymbolsByFile(\n store.getFile(filePath)?.id ?? -1,\n );\n const classSymbol = symbols.find((s) => s.kind === 'class');\n if (!classSymbol) return node;\n\n const symbolNodeId = store.getNodeId('symbol', classSymbol.id);\n if (symbolNodeId == null) return node;\n\n const outEdges = store.getOutgoingEdges(symbolNodeId);\n const renderEdges = outEdges.filter((e) => e.edge_type_name === 'renders_component');\n\n for (const edge of renderEdges) {\n if (budget.remaining <= 0) {\n budget.truncated = true;\n break;\n }\n\n const targetRef = store.getNodeByNodeId(edge.target_node_id);\n if (!targetRef || targetRef.node_type !== 'symbol') continue;\n\n const targetSymbol = store.getSymbolById(targetRef.ref_id);\n if (!targetSymbol) continue;\n\n const targetFile = store.getFileById(targetSymbol.file_id);\n if (!targetFile || visited.has(targetFile.path)) continue;\n\n const targetComp = store.getComponentByFileId(targetFile.id);\n if (!targetComp) continue;\n\n const childNode = buildNode(store, targetComp, targetFile.path, remainingDepth - 1, visited, budget);\n node.children.push(childNode);\n }\n\n return node;\n}\n","import type { Store } from '../db/store.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { notFound } from '../errors.js';\n\nexport interface PennantUsageSite {\n filePath: string;\n line: number;\n usageType: string;\n}\n\nexport interface PennantImpactResult {\n featureName: string;\n definedIn: { filePath: string; line: number }[];\n checkedBy: PennantUsageSite[];\n gatedRoutes: { filePath: string; line: number }[];\n}\n\nexport interface ChangeImpactResult {\n target: { path: string; symbolId?: string };\n dependents: {\n path: string;\n symbolId?: string;\n edgeType: string;\n depth: number;\n }[];\n totalAffected: number;\n truncated?: boolean;\n /** Populated when the target is a Pennant feature flag name */\n pennant?: PennantImpactResult;\n}\n\n/**\n * Determine the impact of changing a file or symbol.\n *\n * Traverses INCOMING edges (who depends on this?) up to `depth` levels,\n * returning all affected files/symbols with their edge types.\n */\nexport function getChangeImpact(\n store: Store,\n opts: { filePath?: string; symbolId?: string },\n depth = 3,\n maxDependents = 200,\n): TraceMcpResult<ChangeImpactResult> {\n let startNodeId: number | undefined;\n let targetPath: string;\n let targetSymbolId: string | undefined;\n\n if (opts.symbolId) {\n const sym = store.getSymbolBySymbolId(opts.symbolId);\n if (!sym) {\n return err(notFound(opts.symbolId));\n }\n startNodeId = store.getNodeId('symbol', sym.id);\n const file = store.getFileById(sym.file_id);\n targetPath = file?.path ?? 'unknown';\n targetSymbolId = opts.symbolId;\n } else if (opts.filePath) {\n const file = store.getFile(opts.filePath);\n if (!file) {\n return err(notFound(opts.filePath));\n }\n targetPath = file.path;\n\n // Start from the file's primary symbol (class) or the file node itself\n const symbols = store.getSymbolsByFile(file.id);\n const primarySymbol = symbols.find((s) => s.kind === 'class') ?? symbols[0];\n if (primarySymbol) {\n startNodeId = store.getNodeId('symbol', primarySymbol.id);\n targetSymbolId = primarySymbol.symbol_id;\n } else {\n startNodeId = store.getNodeId('file', file.id);\n }\n } else {\n return err(notFound('', ['Provide either filePath or symbolId']));\n }\n\n // Check if this might be a Pennant feature flag name (if no node found via symbol/file)\n const pennant = getPennantImpact(store, opts.symbolId ?? opts.filePath ?? '');\n\n if (startNodeId == null) {\n return ok({\n target: { path: targetPath, symbolId: targetSymbolId },\n dependents: [],\n totalAffected: 0,\n });\n }\n\n // Traverse incoming edges recursively\n const dependents: ChangeImpactResult['dependents'] = [];\n const visited = new Set<number>();\n visited.add(startNodeId);\n\n traverseIncoming(store, startNodeId, 1, depth, visited, dependents, maxDependents);\n\n const truncated = dependents.length >= maxDependents;\n\n return ok({\n target: { path: targetPath, symbolId: targetSymbolId },\n dependents,\n totalAffected: dependents.length,\n ...(truncated ? { truncated: true } : {}),\n ...(pennant ? { pennant } : {}),\n });\n}\n\nfunction traverseIncoming(\n store: Store,\n nodeId: number,\n currentDepth: number,\n maxDepth: number,\n visited: Set<number>,\n dependents: ChangeImpactResult['dependents'],\n maxDependents: number,\n): void {\n if (currentDepth > maxDepth) return;\n if (dependents.length >= maxDependents) return;\n\n const incomingEdges = store.getIncomingEdges(nodeId);\n\n for (const edge of incomingEdges) {\n if (dependents.length >= maxDependents) break;\n\n const sourceNodeId = edge.source_node_id;\n if (visited.has(sourceNodeId)) continue;\n visited.add(sourceNodeId);\n\n const nodeRef = store.getNodeByNodeId(sourceNodeId);\n if (!nodeRef) continue;\n\n let filePath: string | undefined;\n let symbolId: string | undefined;\n\n if (nodeRef.node_type === 'symbol') {\n const sym = store.getSymbolById(nodeRef.ref_id);\n if (sym) {\n symbolId = sym.symbol_id;\n const file = store.getFileById(sym.file_id);\n filePath = file?.path;\n }\n } else if (nodeRef.node_type === 'file') {\n const file = store.getFileById(nodeRef.ref_id);\n filePath = file?.path;\n }\n\n if (filePath) {\n dependents.push({\n path: filePath,\n symbolId,\n edgeType: edge.edge_type_name,\n depth: currentDepth,\n });\n }\n\n // Continue traversal\n traverseIncoming(store, sourceNodeId, currentDepth + 1, maxDepth, visited, dependents, maxDependents);\n }\n}\n\n/**\n * Search Pennant feature flag edges for a given feature name.\n * Returns null if no matches found.\n */\nfunction getPennantImpact(store: Store, name: string): PennantImpactResult | null {\n if (!name) return null;\n\n const definedIn: { filePath: string; line: number }[] = [];\n const checkedBy: PennantUsageSite[] = [];\n const gatedRoutes: { filePath: string; line: number }[] = [];\n\n for (const edgeType of ['feature_defined_in', 'feature_checked_by', 'feature_gates_route']) {\n const edges = store.getEdgesByType(edgeType);\n for (const edge of edges) {\n if (!edge.metadata) continue;\n let meta: Record<string, unknown>;\n try { meta = JSON.parse(edge.metadata) as Record<string, unknown>; } catch { continue; }\n if (meta.featureName !== name) continue;\n\n const filePath = String(meta.filePath ?? '');\n const line = Number(meta.line ?? 0);\n\n if (edgeType === 'feature_defined_in') {\n definedIn.push({ filePath, line });\n } else if (edgeType === 'feature_checked_by') {\n checkedBy.push({ filePath, line, usageType: String(meta.usageType ?? '') });\n } else if (edgeType === 'feature_gates_route') {\n gatedRoutes.push({ filePath, line });\n }\n }\n }\n\n if (definedIn.length === 0 && checkedBy.length === 0 && gatedRoutes.length === 0) return null;\n return { featureName: name, definedIn, checkedBy, gatedRoutes };\n}\n","/**\n * get_feature_context tool — finds relevant symbols for a feature description\n * using FTS5 search + graph expansion + hybrid scoring + token budget assembly.\n */\nimport path from 'node:path';\nimport type { Store, SymbolRow, FileRow } from '../db/store.js';\nimport { hybridScore, getTypeBonus, computeRecency } from '../scoring/hybrid.js';\nimport { computePageRank } from '../scoring/pagerank.js';\nimport { assembleContext, type ContextItem } from '../scoring/assembly.js';\nimport { readByteRange } from '../utils/source-reader.js';\n\nexport interface FeatureContextResult {\n description: string;\n items: FeatureContextItem[];\n totalTokens: number;\n truncated: boolean;\n}\n\nexport interface FeatureContextItem {\n symbolId: string;\n name: string;\n kind: string;\n fqn: string | null;\n filePath: string;\n score: number;\n detail: 'full' | 'no_source' | 'signature_only';\n content: string;\n tokens: number;\n}\n\nconst STOPWORDS = new Set([\n 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',\n 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',\n 'should', 'may', 'might', 'can', 'shall', 'to', 'of', 'in', 'for',\n 'on', 'with', 'at', 'by', 'from', 'as', 'into', 'through', 'during',\n 'and', 'or', 'but', 'not', 'no', 'nor', 'so', 'yet', 'both', 'either',\n 'neither', 'each', 'every', 'all', 'any', 'few', 'more', 'most', 'other',\n 'some', 'such', 'than', 'too', 'very', 'just', 'about', 'above', 'after',\n 'before', 'between', 'under', 'over', 'out', 'up', 'down', 'off', 'then',\n 'once', 'here', 'there', 'when', 'where', 'why', 'how', 'what', 'which',\n 'who', 'whom', 'this', 'that', 'these', 'those', 'it', 'its',\n]);\n\n/**\n * Tokenize a feature description into search terms.\n * Splits by spaces, camelCase, and snake_case, then removes stopwords.\n */\nexport function tokenizeDescription(description: string): string[] {\n const raw = description\n // Split camelCase\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n // Split snake_case\n .replace(/_/g, ' ')\n // Remove non-alphanumeric\n .replace(/[^a-zA-Z0-9\\s]/g, ' ')\n .toLowerCase()\n .split(/\\s+/)\n .filter(Boolean);\n\n // Remove stopwords and very short tokens\n return [...new Set(raw.filter((t) => t.length > 1 && !STOPWORDS.has(t)))];\n}\n\nexport function getFeatureContext(\n store: Store,\n rootPath: string,\n description: string,\n tokenBudget = 4000,\n): FeatureContextResult {\n const tokens = tokenizeDescription(description);\n\n if (tokens.length === 0) {\n return { description, items: [], totalTokens: 0, truncated: false };\n }\n\n // Build FTS5 query: each token as a quoted term joined by OR\n const ftsQuery = tokens.map((t) => `\"${t}\"`).join(' OR ');\n\n // Single query: join symbols + files to avoid N+1 lookups in the scoring loop\n interface FtsFullRow {\n symbolId: number;\n symbolIdStr: string;\n rank: number;\n name: string;\n fqn: string | null;\n kind: string;\n byteStart: number;\n byteEnd: number;\n signature: string | null;\n fileId: number;\n filePath: string;\n indexedAt: string;\n }\n\n const ftsResults = store.db.prepare(`\n SELECT\n s.id AS symbolId,\n s.symbol_id AS symbolIdStr,\n rank AS rank,\n s.name,\n s.fqn,\n s.kind,\n s.byte_start AS byteStart,\n s.byte_end AS byteEnd,\n s.signature,\n f.id AS fileId,\n f.path AS filePath,\n f.indexed_at AS indexedAt\n FROM symbols_fts fts\n JOIN symbols s ON s.id = fts.rowid\n JOIN files f ON f.id = s.file_id\n WHERE symbols_fts MATCH ?\n ORDER BY rank\n LIMIT 100\n `).all(ftsQuery) as FtsFullRow[];\n\n if (ftsResults.length === 0) {\n return { description, items: [], totalTokens: 0, truncated: false };\n }\n\n // Build PageRank map\n const pagerankMap = computePageRank(store.db);\n const maxPr = Math.max(...pagerankMap.values(), 0.001);\n\n // Normalize FTS ranks\n const minRank = Math.min(...ftsResults.map((r) => r.rank));\n const maxRank = Math.max(...ftsResults.map((r) => r.rank));\n const rankSpread = maxRank - minRank || 1;\n\n const now = new Date();\n\n // Batch-resolve node IDs for all FTS results in one query (avoids 100× getNodeId)\n const ftsSymIds = ftsResults.map((r) => r.symbolId);\n const ftsNodeMap = store.getNodeIdsBatch('symbol', ftsSymIds);\n\n // Score FTS results — no extra DB lookups needed, all data from the JOIN above\n type ScoredSymbol = { symbol: SymbolRow; file: FileRow; score: number };\n const scored: ScoredSymbol[] = [];\n const scoredById = new Map<string, ScoredSymbol>(); // symbolIdStr → entry for O(1) lookup later\n const seenIds = new Set<number>();\n\n for (const fts of ftsResults) {\n seenIds.add(fts.symbolId);\n\n const relevance = 1 - (fts.rank - minRank) / rankSpread;\n const nodeId = ftsNodeMap.get(fts.symbolId);\n const pr = nodeId ? (pagerankMap.get(nodeId) ?? 0) / maxPr : 0;\n const recency = computeRecency(fts.indexedAt, now);\n const typeBonus = getTypeBonus(fts.kind);\n\n const score = hybridScore({ relevance, pagerank: pr, recency, typeBonus });\n\n // Reconstruct minimal SymbolRow / FileRow shapes needed downstream\n const symbol = {\n id: fts.symbolId,\n symbol_id: fts.symbolIdStr,\n name: fts.name,\n kind: fts.kind,\n fqn: fts.fqn,\n byte_start: fts.byteStart,\n byte_end: fts.byteEnd,\n signature: fts.signature,\n file_id: fts.fileId,\n } as SymbolRow;\n\n const file = {\n id: fts.fileId,\n path: fts.filePath,\n indexed_at: fts.indexedAt,\n } as FileRow;\n\n const entry: ScoredSymbol = { symbol, file, score };\n scored.push(entry);\n scoredById.set(fts.symbolIdStr, entry);\n }\n\n // Sort by initial score before graph expansion so we expand the best matches\n scored.sort((a, b) => b.score - a.score);\n\n // Graph expansion: follow edges 1 hop for top results\n const topResults = scored.slice(0, 10);\n\n // Batch-resolve node IDs for top results (1 query)\n const topSymIds = topResults.map((item) => item.symbol.id);\n const topNodeMap = store.getNodeIdsBatch('symbol', topSymIds);\n const topNodeIds = topResults.map((item) => topNodeMap.get(item.symbol.id)).filter((id): id is number => id != null);\n\n // Fetch all adjacent edges in one query, then batch-resolve refs/symbols/files\n const allEdges = store.getEdgesForNodesBatch(topNodeIds);\n\n const otherNodeIds = [...new Set(allEdges.map((e) =>\n e.pivot_node_id === e.source_node_id ? e.target_node_id : e.source_node_id,\n ))];\n const nodeRefs = store.getNodeRefsBatch(otherNodeIds);\n const symbolRefIds = [...nodeRefs.values()].filter((r) => r.nodeType === 'symbol').map((r) => r.refId);\n const symbolMap = store.getSymbolsByIds(symbolRefIds);\n const fileIds = [...new Set([...symbolMap.values()].map((s) => s.file_id))];\n const fileMap = store.getFilesByIds(fileIds);\n\n for (const edge of allEdges) {\n const otherNodeId = edge.pivot_node_id === edge.source_node_id\n ? edge.target_node_id\n : edge.source_node_id;\n\n const nodeRef = nodeRefs.get(otherNodeId);\n if (!nodeRef || nodeRef.nodeType !== 'symbol') continue;\n\n const sym = symbolMap.get(nodeRef.refId);\n if (!sym || seenIds.has(sym.id)) continue;\n seenIds.add(sym.id);\n\n const file = fileMap.get(sym.file_id);\n if (!file) continue;\n\n const pr = (pagerankMap.get(otherNodeId) ?? 0) / maxPr;\n const recency = computeRecency(file.indexed_at, now);\n const typeBonus = getTypeBonus(sym.kind);\n\n // Graph-expanded items get a reduced relevance score\n const score = hybridScore({ relevance: 0.3, pagerank: pr, recency, typeBonus });\n const entry: ScoredSymbol = { symbol: sym, file, score };\n scored.push(entry);\n scoredById.set(sym.symbol_id, entry);\n }\n\n // Sort by score\n scored.sort((a, b) => b.score - a.score);\n\n // Build context items for assembly\n const contextItems: ContextItem[] = scored.map((item) => {\n const meta = `[${item.symbol.kind}] ${item.symbol.fqn ?? item.symbol.name} (${item.file.path})`;\n\n let source: string | undefined;\n try {\n const absPath = path.resolve(rootPath, item.file.path);\n source = readByteRange(absPath, item.symbol.byte_start, item.symbol.byte_end);\n } catch { /* source unavailable */ }\n\n return {\n id: item.symbol.symbol_id,\n score: item.score,\n source,\n signature: item.symbol.signature ?? undefined,\n metadata: meta,\n };\n });\n\n // Assemble within token budget\n const assembled = assembleContext(contextItems, tokenBudget);\n\n // Build result items\n const items: FeatureContextItem[] = assembled.items.map((ai) => {\n const sym = scoredById.get(ai.id)!;\n return {\n symbolId: ai.id,\n name: sym.symbol.name,\n kind: sym.symbol.kind,\n fqn: sym.symbol.fqn,\n filePath: sym.file.path,\n score: ai.score,\n detail: ai.detail,\n content: ai.content,\n tokens: ai.tokens,\n };\n });\n\n return {\n description,\n items,\n totalTokens: assembled.totalTokens,\n truncated: assembled.truncated,\n };\n}\n","import { estimateTokens } from '../utils/token-counter.js';\n\nexport interface ContextItem {\n id: string;\n score: number;\n /** Full source code of the symbol */\n source?: string;\n /** Just the signature */\n signature?: string;\n /** Metadata line (kind, fqn, file, etc.) */\n metadata: string;\n}\n\nexport type DetailLevel = 'full' | 'no_source' | 'signature_only';\n\nexport interface AssembledItem {\n id: string;\n score: number;\n detail: DetailLevel;\n content: string;\n tokens: number;\n}\n\nexport interface AssembledContext {\n items: AssembledItem[];\n totalTokens: number;\n truncated: boolean;\n}\n\n/**\n * Greedy context assembly within a token budget.\n *\n * Items are sorted by score descending. For each item, we try:\n * 1. full (source + metadata)\n * 2. no_source (signature + metadata)\n * 3. signature_only (just signature)\n * We pick the highest detail level that fits the remaining budget.\n */\nexport function assembleContext(\n items: ContextItem[],\n tokenBudget: number,\n): AssembledContext {\n const sorted = [...items].sort((a, b) => b.score - a.score);\n const result: AssembledItem[] = [];\n let totalTokens = 0;\n let truncated = false;\n\n for (const item of sorted) {\n const remaining = tokenBudget - totalTokens;\n if (remaining <= 0) {\n truncated = true;\n break;\n }\n\n const assembled = tryAssemble(item, remaining);\n if (assembled) {\n result.push(assembled);\n totalTokens += assembled.tokens;\n } else {\n truncated = true;\n }\n }\n\n return { items: result, totalTokens, truncated };\n}\n\nfunction tryAssemble(item: ContextItem, remainingTokens: number): AssembledItem | null {\n // Try full\n if (item.source) {\n const content = `${item.metadata}\\n${item.source}`;\n const tokens = estimateTokens(content);\n if (tokens <= remainingTokens) {\n return { id: item.id, score: item.score, detail: 'full', content, tokens };\n }\n }\n\n // Try no_source (signature + metadata)\n if (item.signature) {\n const content = `${item.metadata}\\n${item.signature}`;\n const tokens = estimateTokens(content);\n if (tokens <= remainingTokens) {\n return { id: item.id, score: item.score, detail: 'no_source', content, tokens };\n }\n }\n\n // Try signature_only\n if (item.signature) {\n const tokens = estimateTokens(item.signature);\n if (tokens <= remainingTokens) {\n return { id: item.id, score: item.score, detail: 'signature_only', content: item.signature, tokens };\n }\n }\n\n return null;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport fg from 'fast-glob';\nimport type { Store } from '../db/store.js';\nimport type { PluginRegistry } from '../plugin-api/registry.js';\nimport type { TraceMcpConfig } from '../config.js';\nimport type { ResolveContext, RawEdge } from '../plugin-api/types.js';\nimport { executeLanguagePlugin, executeFrameworkExtractNodes, executeFrameworkResolveEdges } from '../plugin-api/executor.js';\nimport { hashContent } from '../utils/hasher.js';\nimport { validatePath, validateFileSize, isSensitiveFile } from '../utils/security.js';\nimport { logger } from '../logger.js';\nimport { detectWorkspaces, type WorkspaceInfo } from './monorepo.js';\nimport { EsModuleResolver } from './resolvers/es-modules.js';\nimport { parseEnvFile } from '../utils/env-parser.js';\n\nexport interface IndexingResult {\n totalFiles: number;\n indexed: number;\n skipped: number;\n errors: number;\n durationMs: number;\n}\n\nexport class IndexingPipeline {\n constructor(\n private store: Store,\n private registry: PluginRegistry,\n private config: TraceMcpConfig,\n private rootPath: string,\n ) {}\n\n private workspaces: WorkspaceInfo[] = [];\n // Serializes concurrent indexAll/indexFiles calls — prevents a watcher-triggered\n // indexFiles from racing with an in-progress indexAll (which would overwrite files\n // the watcher already re-indexed with stale content).\n private _lock: Promise<unknown> = Promise.resolve();\n // Cached once per pipeline instance — package.json / composer.json don't change mid-run.\n private _projectContext: ReturnType<typeof this._buildProjectContext> | undefined;\n // File content cache: avoids re-reading files from disk during resolveEdges (Pass 2).\n private _fileContentCache = new Map<string, string>();\n // Pending import edges: collected in Pass 1, resolved to file→file edges in Pass 2d.\n private _pendingImports = new Map<number, { from: string; specifiers: string[]; relPath: string }[]>();\n\n async indexAll(force?: boolean): Promise<IndexingResult> {\n const result = this._lock.then(async () => {\n const start = Date.now();\n this.workspaces = detectWorkspaces(this.rootPath);\n if (this.workspaces.length > 0) {\n logger.info({ workspaces: this.workspaces.map((w) => w.name) }, 'Detected workspaces');\n }\n const filePaths = await this.collectFiles();\n return this.runPipeline(filePaths, force ?? false, start);\n });\n this._lock = result.catch(() => {});\n return result as Promise<IndexingResult>;\n }\n\n /** Remove deleted files from the index. */\n deleteFiles(filePaths: string[]): void {\n for (const fp of filePaths) {\n const relPath = path.isAbsolute(fp) ? path.relative(this.rootPath, fp) : fp;\n const file = this.store.getFile(relPath);\n if (file) {\n this.store.deleteFile(file.id);\n logger.info({ file: relPath }, 'Deleted file from index');\n }\n }\n }\n\n async indexFiles(filePaths: string[]): Promise<IndexingResult> {\n const result = this._lock.then(async () => {\n const start = Date.now();\n const relPaths: string[] = [];\n for (const fp of filePaths) {\n const rel = path.isAbsolute(fp) ? path.relative(this.rootPath, fp) : fp;\n const check = validatePath(rel, this.rootPath);\n if (check.isErr()) {\n logger.warn({ file: fp }, 'Path traversal blocked in indexFiles');\n continue;\n }\n relPaths.push(rel);\n }\n return this.runPipeline(relPaths, false, start);\n });\n this._lock = result.catch(() => {});\n return result as Promise<IndexingResult>;\n }\n\n private async runPipeline(\n relPaths: string[],\n force: boolean,\n startMs: number,\n ): Promise<IndexingResult> {\n const result: IndexingResult = {\n totalFiles: relPaths.length,\n indexed: 0,\n skipped: 0,\n errors: 0,\n durationMs: 0,\n };\n\n // Clear cached project context so framework activation uses fresh package.json/composer.json\n this._projectContext = undefined;\n\n // Register edge types from framework plugins\n this.registerFrameworkEdgeTypes();\n\n // Pass 1: per-file extraction\n for (const relPath of relPaths) {\n const ok = await this.indexSingleFile(relPath, force);\n if (ok === 'indexed') result.indexed++;\n else if (ok === 'skipped') result.skipped++;\n else result.errors++;\n }\n\n // Pass 2: resolve edges (framework plugins)\n await this.resolveEdges();\n\n // Pass 2b: ORM associations → graph edges (resolved after all entities indexed)\n this.resolveOrmAssociationEdges();\n\n // Pass 2c: TypeScript heritage → graph edges (extends/implements → find_references)\n this.resolveTypeScriptHeritageEdges();\n\n // Pass 2d: ES module imports → file→file edges (enables dependency graph + dead export analysis)\n this.resolveEsmImportEdges();\n\n // Pass 2e: test_covers edges — test file imports source file → test_covers edge\n this.resolveTestCoversEdges();\n\n // Pass 3: Index .env files (keys + type metadata only, never store values)\n await this.indexEnvFiles(force);\n\n // Release memory — file content is no longer needed after Pass 2\n this._fileContentCache.clear();\n this._pendingImports.clear();\n\n result.durationMs = Date.now() - startMs;\n logger.info(result, 'Indexing pipeline completed');\n return result;\n }\n\n private async indexSingleFile(\n relPath: string,\n force: boolean,\n ): Promise<'indexed' | 'skipped' | 'error'> {\n const absPath = path.resolve(this.rootPath, relPath);\n\n // Defence-in-depth: reject paths that escape the project root\n const pathCheck = validatePath(relPath, this.rootPath);\n if (pathCheck.isErr()) {\n logger.warn({ file: relPath }, 'Path traversal blocked');\n return 'error';\n }\n\n // Reject symlinks to prevent escaping the project root\n try {\n if (fs.lstatSync(absPath).isSymbolicLink()) {\n logger.warn({ file: relPath }, 'Symlink skipped');\n return 'error';\n }\n } catch {\n // lstat failed — file may not exist; readFileSync below will catch it\n }\n\n // Block sensitive files (credentials, keys, secrets) from indexing\n if (isSensitiveFile(relPath)) {\n logger.warn({ file: relPath }, 'Sensitive file blocked from indexing');\n return 'skipped';\n }\n\n let content: Buffer;\n try {\n content = fs.readFileSync(absPath);\n } catch {\n logger.warn({ file: relPath }, 'Cannot read file');\n return 'error';\n }\n\n // Reject oversized files (default 1 MB) to prevent OOM\n const sizeCheck = validateFileSize(content.length);\n if (sizeCheck.isErr()) {\n logger.warn({ file: relPath, size: content.length }, 'File too large, skipping');\n return 'error';\n }\n\n // Cache content for Pass 2 (resolveEdges reads files again)\n this._fileContentCache.set(relPath, content.toString('utf-8'));\n\n const hash = hashContent(content);\n const existing = this.store.getFile(relPath);\n\n // Skip if unchanged\n if (!force && existing && existing.content_hash === hash) {\n return 'skipped';\n }\n\n // Find matching language plugin\n const plugin = this.registry.getLanguagePluginForFile(relPath);\n if (!plugin) {\n return 'skipped';\n }\n\n // Execute language plugin\n const parseResult = await executeLanguagePlugin(plugin, relPath, content);\n if (parseResult.isErr()) {\n logger.error({ file: relPath, error: parseResult.error }, 'Language plugin failed');\n return 'error';\n }\n\n const parsed = parseResult.value;\n const language = parsed.language ?? this.detectLanguage(relPath);\n\n // Determine workspace for this file\n const workspace = this.resolveWorkspace(relPath);\n\n // Upsert file record\n let fileId: number;\n if (existing) {\n fileId = existing.id;\n this.store.deleteSymbolsByFile(fileId);\n this.store.deleteEdgesForFileNodes(fileId);\n this.store.deleteEntitiesByFile(fileId);\n this.store.updateFileHash(fileId, hash, content.length);\n this.store.updateFileStatus(fileId, parsed.status, parsed.frameworkRole);\n if (workspace) this.store.updateFileWorkspace(fileId, workspace);\n } else {\n fileId = this.store.insertFile(relPath, language, hash, content.length, workspace);\n if (parsed.status !== 'ok' || parsed.frameworkRole) {\n this.store.updateFileStatus(fileId, parsed.status, parsed.frameworkRole);\n }\n }\n\n // Insert symbols\n if (parsed.symbols.length > 0) {\n this.store.insertSymbols(fileId, parsed.symbols);\n }\n\n // Insert edges from language plugin\n if (parsed.edges?.length) {\n // Separate import edges (need ESM resolution in pass 2d) from other edges\n const importEdges: typeof parsed.edges = [];\n const otherEdges: typeof parsed.edges = [];\n for (const edge of parsed.edges) {\n if (edge.edgeType === 'imports' && !edge.sourceNodeType && !edge.sourceSymbolId) {\n importEdges.push(edge);\n } else {\n otherEdges.push(edge);\n }\n }\n if (otherEdges.length > 0) this.storeRawEdges(otherEdges);\n if (importEdges.length > 0) {\n this._pendingImports.set(\n fileId,\n importEdges.map((e) => ({\n from: (e.metadata as Record<string, unknown>)?.['from'] as string ?? '',\n specifiers: ((e.metadata as Record<string, unknown>)?.['specifiers'] as string[]) ?? [],\n relPath,\n })),\n );\n }\n }\n\n // Insert routes, components, migrations, ORM models\n if (parsed.routes?.length) {\n for (const r of parsed.routes) this.store.insertRoute(r, fileId);\n }\n if (parsed.components?.length) {\n for (const c of parsed.components) this.store.insertComponent(c, fileId);\n }\n if (parsed.migrations?.length) {\n for (const m of parsed.migrations) this.store.insertMigration(m, fileId);\n }\n if (parsed.ormModels?.length) {\n this.storeOrmResults(parsed.ormModels, parsed.ormAssociations ?? [], fileId);\n }\n\n // Framework extractNodes (pass 1)\n await this.runFrameworkExtractNodes(relPath, content, language, fileId);\n\n return 'indexed';\n }\n\n private async runFrameworkExtractNodes(\n relPath: string,\n content: Buffer,\n language: string,\n fileId: number,\n ): Promise<void> {\n const ctx = this.buildProjectContext();\n const activeResult = this.registry.getActiveFrameworkPlugins(ctx);\n if (activeResult.isErr()) {\n logger.warn({ error: activeResult.error }, 'Failed to get active framework plugins');\n return;\n }\n\n for (const plugin of activeResult.value) {\n const result = await executeFrameworkExtractNodes(plugin, relPath, content, language);\n if (result.isErr() || !result.value) continue;\n\n const fwResult = result.value;\n if (fwResult.symbols.length > 0) {\n this.store.insertSymbols(fileId, fwResult.symbols);\n }\n if (fwResult.edges?.length) {\n this.storeRawEdges(fwResult.edges);\n }\n if (fwResult.routes?.length) {\n for (const r of fwResult.routes) this.store.insertRoute(r, fileId);\n }\n if (fwResult.components?.length) {\n for (const c of fwResult.components) this.store.insertComponent(c, fileId);\n }\n if (fwResult.migrations?.length) {\n for (const m of fwResult.migrations) this.store.insertMigration(m, fileId);\n }\n if (fwResult.ormModels?.length) {\n this.storeOrmResults(fwResult.ormModels, fwResult.ormAssociations ?? [], fileId);\n }\n if (fwResult.rnScreens?.length) {\n for (const s of fwResult.rnScreens) this.store.insertRnScreen(s, fileId);\n }\n if (fwResult.frameworkRole) {\n this.store.updateFileStatus(fileId, fwResult.status, fwResult.frameworkRole);\n }\n }\n }\n\n private storeOrmResults(\n models: import('../plugin-api/types.js').RawOrmModel[],\n associations: import('../plugin-api/types.js').RawOrmAssociation[],\n fileId: number,\n ): void {\n // Insert models first, collect name → id map\n const modelIdMap = new Map<string, number>();\n for (const m of models) {\n const id = this.store.insertOrmModel(m, fileId);\n modelIdMap.set(m.name, id);\n }\n\n // Insert associations — resolve target ID best-effort (may be null if not indexed yet)\n for (const assoc of associations) {\n const sourceId = modelIdMap.get(assoc.sourceModelName)\n ?? this.store.getOrmModelByName(assoc.sourceModelName)?.id;\n if (sourceId == null) continue;\n\n const targetId = modelIdMap.get(assoc.targetModelName)\n ?? this.store.getOrmModelByName(assoc.targetModelName)?.id\n ?? null;\n\n this.store.insertOrmAssociation(\n sourceId,\n targetId,\n assoc.targetModelName,\n assoc.kind,\n assoc.options,\n fileId,\n );\n }\n }\n\n private async resolveEdges(): Promise<void> {\n const ctx = this.buildProjectContext();\n const activeResult = this.registry.getActiveFrameworkPlugins(ctx);\n if (activeResult.isErr()) return;\n\n const resolveCtx = this.buildResolveContext();\n\n for (const plugin of activeResult.value) {\n const result = await executeFrameworkResolveEdges(plugin, resolveCtx);\n if (result.isErr()) continue;\n this.storeRawEdges(result.value);\n }\n }\n\n /** Convert ORM associations (orm_associations table) into graph edges. */\n private resolveOrmAssociationEdges(): void {\n const associations = this.store.getAllOrmAssociations();\n if (associations.length === 0) return;\n\n // Build model ID → ORM type map\n const allModels = this.store.getAllOrmModels();\n const modelOrmMap = new Map<number, string>();\n for (const m of allModels) {\n modelOrmMap.set(m.id, m.orm);\n }\n\n // ORM-specific kind → edge type name mapping\n const ormKindToEdgeType: Record<string, Record<string, string>> = {\n mongoose: {\n ref: 'mongoose_references',\n discriminator: 'mongoose_discriminates',\n },\n sequelize: {\n hasMany: 'sequelize_has_many',\n belongsTo: 'sequelize_belongs_to',\n belongsToMany: 'sequelize_belongs_to_many',\n hasOne: 'sequelize_has_one',\n },\n typeorm: {\n OneToMany: 'typeorm_one_to_many',\n ManyToOne: 'typeorm_many_to_one',\n OneToOne: 'typeorm_one_to_one',\n ManyToMany: 'typeorm_many_to_many',\n },\n prisma: {\n hasMany: 'prisma_relation',\n belongsTo: 'prisma_relation',\n },\n drizzle: {\n hasMany: 'drizzle_relation',\n belongsTo: 'drizzle_relation',\n },\n };\n\n for (const assoc of associations) {\n // Resolve target model if it wasn't available during Pass 1\n let targetModelId = assoc.target_model_id;\n if (targetModelId == null && assoc.target_model_name) {\n const target = this.store.getOrmModelByName(assoc.target_model_name);\n if (target) targetModelId = target.id;\n }\n if (targetModelId == null) continue;\n\n const sourceNodeId = this.store.getNodeId('orm_model', assoc.source_model_id);\n const targetNodeId = this.store.getNodeId('orm_model', targetModelId);\n if (sourceNodeId == null || targetNodeId == null) continue;\n\n const orm = modelOrmMap.get(assoc.source_model_id) ?? 'unknown';\n const ormMap = ormKindToEdgeType[orm];\n const edgeType = ormMap?.[assoc.kind] ?? `orm_${assoc.kind}`;\n const insertResult = this.store.insertEdge(sourceNodeId, targetNodeId, edgeType, true, undefined, false);\n if (insertResult.isErr()) {\n logger.warn({ edgeType, orm, kind: assoc.kind, error: insertResult.error }, 'Failed to insert ORM edge');\n }\n }\n }\n\n /**\n * Pass 2c: Resolve TypeScript extends/implements metadata into graph edges.\n * Builds a class/interface name → symbol DB id map, then creates\n * ts_extends and ts_implements edges for all symbols that have heritage metadata.\n */\n private resolveTypeScriptHeritageEdges(): void {\n const symbolsWithHeritage = this.store.getSymbolsWithHeritage();\n if (symbolsWithHeritage.length === 0) return;\n\n // Build name → {id, kind} index across ALL TypeScript symbols (classes + interfaces)\n const nameIndex = new Map<string, { id: number; kind: string }[]>();\n const allSymbols = this.store.db.prepare(\n \"SELECT id, name, kind FROM symbols WHERE kind IN ('class', 'interface')\",\n ).all() as { id: number; name: string; kind: string }[];\n\n for (const s of allSymbols) {\n const list = nameIndex.get(s.name) ?? [];\n list.push({ id: s.id, kind: s.kind });\n nameIndex.set(s.name, list);\n }\n\n let created = 0;\n\n for (const sym of symbolsWithHeritage) {\n let meta: Record<string, unknown> = {};\n try { if (sym.metadata) meta = JSON.parse(sym.metadata) as Record<string, unknown>; } catch { continue; }\n const sourceNodeId = this.store.getNodeId('symbol', sym.id);\n if (sourceNodeId == null) continue;\n\n // Process extends\n const ext = meta['extends'];\n const extNames = Array.isArray(ext) ? ext as string[] : typeof ext === 'string' ? [ext] : [];\n for (const targetName of extNames) {\n const targets = nameIndex.get(targetName);\n if (!targets?.length) continue;\n const target = targets[0]; // first match\n const targetNodeId = this.store.getNodeId('symbol', target.id);\n if (targetNodeId == null) continue;\n this.store.insertEdge(sourceNodeId, targetNodeId, 'ts_extends', true);\n created++;\n }\n\n // Process implements\n const impl = meta['implements'];\n if (Array.isArray(impl)) {\n for (const targetName of impl as string[]) {\n const targets = nameIndex.get(targetName);\n if (!targets?.length) continue;\n const target = targets.find((t) => t.kind === 'interface') ?? targets[0];\n const targetNodeId = this.store.getNodeId('symbol', target.id);\n if (targetNodeId == null) continue;\n this.store.insertEdge(sourceNodeId, targetNodeId, 'ts_implements', true);\n created++;\n }\n }\n }\n\n if (created > 0) {\n logger.info({ edges: created }, 'TypeScript heritage edges resolved');\n }\n }\n\n /**\n * Pass 2d: Resolve ES module import specifiers to file→file graph edges.\n * Uses the pending imports collected during Pass 1 + the EsModuleResolver.\n */\n private resolveEsmImportEdges(): void {\n if (this._pendingImports.size === 0) return;\n\n let resolver: EsModuleResolver;\n try {\n const tsconfigPath = fs.existsSync(path.join(this.rootPath, 'tsconfig.json'))\n ? path.join(this.rootPath, 'tsconfig.json')\n : undefined;\n resolver = new EsModuleResolver(this.rootPath, tsconfigPath);\n } catch {\n logger.warn('EsModuleResolver init failed — skipping import edge resolution');\n return;\n }\n\n let created = 0;\n\n // Pre-build lookup maps to avoid N+1 per file/import\n const pendingFileIds = Array.from(this._pendingImports.keys());\n const fileMap = this.store.getFilesByIds(pendingFileIds);\n const fileNodeMap = this.store.getNodeIdsBatch('file', pendingFileIds);\n\n // Pre-build path → file lookup for target resolution\n const allFiles = this.store.getAllFiles();\n const pathToFile = new Map<string, { id: number }>();\n for (const f of allFiles) pathToFile.set(f.path, f);\n const allFileIds = allFiles.map((f) => f.id);\n const allFileNodeMap = this.store.getNodeIdsBatch('file', allFileIds);\n\n for (const [fileId, imports] of this._pendingImports) {\n const file = fileMap.get(fileId);\n if (!file) continue;\n\n const absSource = path.resolve(this.rootPath, file.path);\n const sourceNodeId = fileNodeMap.get(fileId);\n if (sourceNodeId == null) continue;\n\n for (const { from, specifiers } of imports) {\n // Skip bare specifiers (node_modules) — only resolve project-local imports\n if (!from.startsWith('.') && !from.startsWith('/') && !from.startsWith('@/') && !from.startsWith('~')) continue;\n\n const resolved = resolver.resolve(from, absSource);\n if (!resolved) continue;\n\n const relTarget = path.relative(this.rootPath, resolved);\n const targetFile = pathToFile.get(relTarget);\n if (!targetFile) continue;\n\n const targetNodeId = allFileNodeMap.get(targetFile.id);\n if (targetNodeId == null) continue;\n\n this.store.insertEdge(\n sourceNodeId,\n targetNodeId,\n 'imports',\n true,\n { from, specifiers },\n );\n created++;\n }\n }\n\n if (created > 0) {\n logger.info({ edges: created }, 'ES module import edges resolved');\n }\n }\n\n private static readonly TEST_PATH_RE = /\\.(test|spec)\\.[jt]sx?$|__tests__\\//;\n\n /**\n * Pass 2e: Create test_covers edges.\n * For each test file, examine its outgoing `imports` edges.\n * If the imported file is NOT a test file, create a `test_covers` edge:\n * test_file →[test_covers]→ source_file\n */\n private resolveTestCoversEdges(): void {\n const allFiles = this.store.getAllFiles();\n const testFiles = allFiles.filter((f) => IndexingPipeline.TEST_PATH_RE.test(f.path));\n if (testFiles.length === 0) return;\n\n let created = 0;\n\n for (const testFile of testFiles) {\n const testNodeId = this.store.getNodeId('file', testFile.id);\n if (testNodeId == null) continue;\n\n // Get outgoing import edges from this test file\n const outgoing = this.store.getOutgoingEdges(testNodeId);\n\n for (const edge of outgoing) {\n if (edge.edge_type_name !== 'imports') continue;\n\n const targetRef = this.store.getNodeRef(edge.target_node_id);\n if (!targetRef || targetRef.nodeType !== 'file') continue;\n\n const targetFile = this.store.getFileById(targetRef.refId);\n if (!targetFile) continue;\n\n // Skip if target is also a test file\n if (IndexingPipeline.TEST_PATH_RE.test(targetFile.path)) continue;\n\n // Create test_covers edge: test → source\n this.store.insertEdge(\n testNodeId,\n edge.target_node_id,\n 'test_covers',\n true,\n { test_file: testFile.path },\n );\n created++;\n }\n }\n\n if (created > 0) {\n logger.info({ edges: created }, 'test_covers edges resolved');\n }\n }\n\n private storeRawEdges(edges: RawEdge[]): void {\n if (edges.length === 0) return;\n\n // ── Pre-load all caches to eliminate per-edge SELECTs ──\n\n // 1. symbolIdStr → nodeId\n const symbolIdStrs = new Set<string>();\n for (const edge of edges) {\n if (edge.sourceSymbolId) symbolIdStrs.add(edge.sourceSymbolId);\n if (edge.targetSymbolId) symbolIdStrs.add(edge.targetSymbolId);\n }\n\n const symbolNodeCache = new Map<string, number>();\n if (symbolIdStrs.size > 0) {\n const arr = Array.from(symbolIdStrs);\n const placeholders = arr.map(() => '?').join(',');\n const rows = this.store.db.prepare(\n `SELECT s.symbol_id, n.id AS node_id\n FROM symbols s\n JOIN nodes n ON n.node_type = 'symbol' AND n.ref_id = s.id\n WHERE s.symbol_id IN (${placeholders})`,\n ).all(...arr) as Array<{ symbol_id: string; node_id: number }>;\n for (const row of rows) {\n symbolNodeCache.set(row.symbol_id, row.node_id);\n }\n }\n\n // 2. (nodeType, refId) → nodeId — batch by nodeType\n const refIdsByType = new Map<string, Set<number>>();\n for (const edge of edges) {\n if (edge.sourceNodeType && edge.sourceRefId != null) {\n let s = refIdsByType.get(edge.sourceNodeType);\n if (!s) { s = new Set(); refIdsByType.set(edge.sourceNodeType, s); }\n s.add(edge.sourceRefId);\n }\n if (edge.targetNodeType && edge.targetRefId != null) {\n let s = refIdsByType.get(edge.targetNodeType);\n if (!s) { s = new Set(); refIdsByType.set(edge.targetNodeType, s); }\n s.add(edge.targetRefId);\n }\n }\n const typeRefCache = new Map<string, number>(); // \"type:refId\" → nodeId\n for (const [nodeType, refIds] of refIdsByType) {\n const batch = this.store.getNodeIdsBatch(nodeType, Array.from(refIds));\n for (const [refId, nodeId] of batch) {\n typeRefCache.set(`${nodeType}:${refId}`, nodeId);\n }\n }\n\n // 3. edgeTypeName → edgeTypeId (avoids per-edge SELECT in insertEdge)\n const edgeTypeNames = new Set<string>();\n for (const edge of edges) edgeTypeNames.add(edge.edgeType);\n const edgeTypeCache = new Map<string, number>();\n for (const name of edgeTypeNames) {\n const row = this.store.db.prepare('SELECT id FROM edge_types WHERE name = ?').get(name) as { id: number } | undefined;\n if (row) edgeTypeCache.set(name, row.id);\n }\n\n // ── Batch all inserts in a single transaction with a prepared statement ──\n const insertStmt = this.store.db.prepare(\n `INSERT OR IGNORE INTO edges (source_node_id, target_node_id, edge_type_id, resolved, metadata, is_cross_ws)\n VALUES (?, ?, ?, ?, ?, ?)`,\n );\n\n const insertBatch = this.store.db.transaction(() => {\n for (const edge of edges) {\n const sourceNodeId = this.resolveNodeId(edge, symbolNodeCache, typeRefCache);\n if (sourceNodeId == null) continue;\n // For source-only edges (e.g. livewire_dispatches, livewire_listens) where\n // there is no target node, use the source as target to preserve the edge + metadata.\n const targetNodeId = this.resolveTargetNodeId(edge, symbolNodeCache, typeRefCache) ?? sourceNodeId;\n\n const edgeTypeId = edgeTypeCache.get(edge.edgeType);\n if (edgeTypeId == null) continue;\n\n const isCrossWs = this.isEdgeCrossWorkspace(sourceNodeId, targetNodeId);\n\n insertStmt.run(\n sourceNodeId,\n targetNodeId,\n edgeTypeId,\n (edge.resolved ?? true) ? 1 : 0,\n edge.metadata ? JSON.stringify(edge.metadata) : null,\n isCrossWs ? 1 : 0,\n );\n }\n });\n insertBatch();\n }\n\n private resolveNodeId(\n edge: RawEdge,\n symbolNodeCache: Map<string, number>,\n typeRefCache: Map<string, number>,\n ): number | undefined {\n if (edge.sourceNodeType && edge.sourceRefId != null) {\n return typeRefCache.get(`${edge.sourceNodeType}:${edge.sourceRefId}`)\n ?? this.store.getNodeId(edge.sourceNodeType, edge.sourceRefId);\n }\n if (edge.sourceSymbolId) {\n return symbolNodeCache.get(edge.sourceSymbolId);\n }\n return undefined;\n }\n\n private resolveTargetNodeId(\n edge: RawEdge,\n symbolNodeCache: Map<string, number>,\n typeRefCache: Map<string, number>,\n ): number | undefined {\n if (edge.targetNodeType && edge.targetRefId != null) {\n return typeRefCache.get(`${edge.targetNodeType}:${edge.targetRefId}`)\n ?? this.store.getNodeId(edge.targetNodeType, edge.targetRefId);\n }\n if (edge.targetSymbolId) {\n return symbolNodeCache.get(edge.targetSymbolId);\n }\n return undefined;\n }\n\n private buildProjectContext() {\n if (!this._projectContext) {\n this._projectContext = this._buildProjectContext();\n }\n return this._projectContext;\n }\n\n private _buildProjectContext() {\n let packageJson: Record<string, unknown> | undefined;\n try {\n const pkgPath = path.resolve(this.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n packageJson = JSON.parse(content) as Record<string, unknown>;\n } catch {\n // No package.json found\n }\n\n let composerJson: Record<string, unknown> | undefined;\n try {\n const composerPath = path.resolve(this.rootPath, 'composer.json');\n const content = fs.readFileSync(composerPath, 'utf-8');\n composerJson = JSON.parse(content) as Record<string, unknown>;\n } catch {\n // No composer.json found\n }\n\n let pyprojectToml: Record<string, unknown> | undefined;\n try {\n const tomlPath = path.resolve(this.rootPath, 'pyproject.toml');\n const content = fs.readFileSync(tomlPath, 'utf-8');\n // Lightweight TOML parse — extract [project] dependencies and [tool.poetry] dependencies\n const deps: string[] = [];\n const depBlockRe = /\\[(?:project|tool\\.poetry)\\.?dependencies\\]([^[]*)/g;\n let m: RegExpExecArray | null;\n while ((m = depBlockRe.exec(content)) !== null) {\n const block = m[1];\n for (const line of block.split('\\n')) {\n const pkg = line.match(/^\\s*([a-zA-Z0-9_-]+)/);\n if (pkg) deps.push(pkg[1].toLowerCase());\n }\n }\n // Also parse inline dependencies array: dependencies = [\"fastapi>=0.100\", ...]\n const inlineDeps = content.match(/dependencies\\s*=\\s*\\[([^\\]]*)\\]/);\n if (inlineDeps) {\n const items = inlineDeps[1].matchAll(/[\"']([a-zA-Z0-9_-]+)[^\"']*[\"']/g);\n for (const item of items) {\n deps.push(item[1].toLowerCase());\n }\n }\n pyprojectToml = { _parsedDeps: deps, _raw: content } as Record<string, unknown>;\n } catch {\n // No pyproject.toml found\n }\n\n let requirementsTxt: string[] | undefined;\n try {\n const reqPath = path.resolve(this.rootPath, 'requirements.txt');\n const content = fs.readFileSync(reqPath, 'utf-8');\n requirementsTxt = content\n .split('\\n')\n .map((l) => l.replace(/#.*/, '').trim())\n .filter((l) => l && !l.startsWith('-'))\n .map((l) => l.split(/[>=<!\\[;]/)[0].trim().toLowerCase());\n } catch {\n // No requirements.txt found\n }\n\n return {\n rootPath: this.rootPath,\n packageJson,\n composerJson,\n pyprojectToml,\n requirementsTxt,\n configFiles: [],\n };\n }\n\n private registerFrameworkEdgeTypes(): void {\n const ctx = this.buildProjectContext();\n const activeResult = this.registry.getActiveFrameworkPlugins(ctx);\n if (activeResult.isErr()) return;\n\n for (const plugin of activeResult.value) {\n const schema = plugin.registerSchema();\n if (schema.edgeTypes) {\n for (const et of schema.edgeTypes) {\n this.store.ensureEdgeType(et.name, et.category, et.description ?? '');\n }\n }\n }\n }\n\n private buildResolveContext(): ResolveContext {\n const store = this.store;\n return {\n rootPath: this.rootPath,\n getAllFiles: () => store.getAllFiles().map((f) => ({\n id: f.id,\n path: f.path,\n language: f.language,\n })),\n getSymbolsByFile: (fileId: number) =>\n store.getSymbolsByFile(fileId).map((s) => ({\n id: s.id,\n symbolId: s.symbol_id,\n name: s.name,\n kind: s.kind,\n fqn: s.fqn,\n lineStart: s.line_start,\n lineEnd: s.line_end,\n metadata: s.metadata ? JSON.parse(s.metadata) as Record<string, unknown> : null,\n })),\n getSymbolByFqn: (fqn: string) => {\n const s = store.getSymbolByFqn(fqn);\n return s ? { id: s.id, symbolId: s.symbol_id } : undefined;\n },\n getNodeId: (nodeType: string, refId: number) => store.getNodeId(nodeType, refId),\n createNodeIfNeeded: (nodeType: string, refId: number) => store.createNode(nodeType, refId),\n readFile: (relPath: string) => {\n // Use Pass 1 cache first, fall back to disk\n const cached = this._fileContentCache.get(relPath);\n if (cached !== undefined) return cached;\n try {\n return fs.readFileSync(path.resolve(this.rootPath, relPath), 'utf-8');\n } catch { return undefined; }\n },\n };\n }\n\n private resolveWorkspace(relPath: string): string | null {\n for (const ws of this.workspaces) {\n if (relPath.startsWith(ws.path + '/') || relPath === ws.path) {\n return ws.name;\n }\n }\n return null;\n }\n\n private isEdgeCrossWorkspace(sourceNodeId: number, targetNodeId: number): boolean {\n if (this.workspaces.length === 0) return false;\n\n const sourceWs = this.getWorkspaceForNode(sourceNodeId);\n const targetWs = this.getWorkspaceForNode(targetNodeId);\n\n if (sourceWs == null || targetWs == null) return false;\n return sourceWs !== targetWs;\n }\n\n private getWorkspaceForNode(nodeId: number): string | null {\n const ref = this.store.getNodeRef(nodeId);\n if (!ref) return null;\n\n if (ref.nodeType === 'file') {\n const file = this.store.getFileById(ref.refId);\n return file?.workspace ?? null;\n }\n if (ref.nodeType === 'symbol') {\n const sym = this.store.getSymbolById(ref.refId);\n if (!sym) return null;\n const file = this.store.getFileById(sym.file_id);\n return file?.workspace ?? null;\n }\n return null;\n }\n\n private async collectFiles(): Promise<string[]> {\n const entries = await fg(this.config.include, {\n cwd: this.rootPath,\n ignore: this.config.exclude,\n dot: false,\n absolute: false,\n onlyFiles: true,\n });\n return entries;\n }\n\n // ─── .env file indexing ───────────────────────────────────────────\n\n private static readonly ENV_GLOB = ['.env', '.env.*', '.env.local', '**/.env', '**/.env.*'];\n\n private async indexEnvFiles(force: boolean): Promise<void> {\n const envPaths = await fg(IndexingPipeline.ENV_GLOB, {\n cwd: this.rootPath,\n ignore: this.config.exclude,\n dot: true,\n absolute: false,\n onlyFiles: true,\n });\n\n if (envPaths.length === 0) return;\n\n logger.info({ count: envPaths.length }, 'Indexing .env files (keys only)');\n\n for (const relPath of envPaths) {\n const absPath = path.resolve(this.rootPath, relPath);\n\n // Defence-in-depth\n const pathCheck = validatePath(relPath, this.rootPath);\n if (pathCheck.isErr()) continue;\n\n let content: string;\n try {\n content = fs.readFileSync(absPath, 'utf-8');\n } catch {\n logger.warn({ file: relPath }, 'Cannot read .env file');\n continue;\n }\n\n const hash = hashContent(Buffer.from(content));\n const existing = this.store.getFile(relPath);\n\n if (!force && existing && existing.content_hash === hash) continue;\n\n const entries = parseEnvFile(content);\n\n // Upsert file record (language = 'env', framework_role = 'config')\n let fileId: number;\n if (existing) {\n fileId = existing.id;\n this.store.deleteEnvVarsByFile(fileId);\n this.store.updateFileHash(fileId, hash, content.length);\n } else {\n fileId = this.store.insertFile(relPath, 'env', hash, content.length);\n this.store.updateFileStatus(fileId, 'ok', 'config');\n }\n\n for (const entry of entries) {\n this.store.insertEnvVar(fileId, {\n key: entry.key,\n valueType: entry.valueType,\n valueFormat: entry.valueFormat,\n comment: entry.comment,\n quoted: entry.quoted,\n line: entry.line,\n });\n }\n\n logger.debug({ file: relPath, keys: entries.length }, '.env file indexed');\n }\n }\n\n private detectLanguage(filePath: string): string {\n const ext = path.extname(filePath).slice(1);\n const map: Record<string, string> = {\n php: 'php',\n ts: 'typescript',\n tsx: 'typescript',\n js: 'javascript',\n jsx: 'javascript',\n mjs: 'javascript',\n mts: 'typescript',\n vue: 'vue',\n };\n return map[ext] ?? ext;\n }\n}\n","import type { LanguagePlugin, FrameworkPlugin, FileParseResult, RawEdge, ResolveContext } from './types.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { pluginError, parseError } from '../errors.js';\nimport { logger } from '../logger.js';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\nexport async function executeLanguagePlugin(\n plugin: LanguagePlugin,\n filePath: string,\n content: Buffer,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n): Promise<TraceMcpResult<FileParseResult>> {\n try {\n const result = await withTimeout(\n () => plugin.extractSymbols(filePath, content),\n timeoutMs,\n `${plugin.manifest.name}.extractSymbols`,\n );\n return result;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n logger.error({ plugin: plugin.manifest.name, file: filePath, error: msg }, 'Language plugin error');\n return ok({\n language: undefined,\n status: 'error',\n symbols: [],\n warnings: [`Plugin ${plugin.manifest.name} failed: ${msg}`],\n });\n }\n}\n\nexport async function executeFrameworkExtractNodes(\n plugin: FrameworkPlugin,\n filePath: string,\n content: Buffer,\n language: string,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n): Promise<TraceMcpResult<FileParseResult | null>> {\n if (!plugin.extractNodes) return ok(null);\n\n try {\n const result = await withTimeout(\n () => plugin.extractNodes!(filePath, content, language),\n timeoutMs,\n `${plugin.manifest.name}.extractNodes`,\n );\n return result.map((r) => r as FileParseResult | null);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n logger.error({ plugin: plugin.manifest.name, file: filePath, error: msg }, 'Framework extractNodes error');\n return ok(null);\n }\n}\n\nexport async function executeFrameworkResolveEdges(\n plugin: FrameworkPlugin,\n ctx: ResolveContext,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n): Promise<TraceMcpResult<RawEdge[]>> {\n if (!plugin.resolveEdges) return ok([]);\n\n try {\n const result = await withTimeout(\n () => plugin.resolveEdges!(ctx),\n timeoutMs,\n `${plugin.manifest.name}.resolveEdges`,\n );\n return result;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n logger.error({ plugin: plugin.manifest.name, error: msg }, 'Framework resolveEdges error');\n return ok([]);\n }\n}\n\nasync function withTimeout<T>(\n fn: () => T,\n timeoutMs: number,\n operationName: string,\n): Promise<T> {\n // For synchronous functions, just call directly\n const result = fn();\n\n if (result instanceof Promise) {\n return Promise.race([\n result,\n new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(`Timeout: ${operationName} exceeded ${timeoutMs}ms`)),\n timeoutMs,\n ),\n ),\n ]);\n }\n\n return result;\n}\n","import crypto from 'node:crypto';\nimport fs from 'node:fs';\n\n/** Hash file content for change detection. MD5 for speed. */\nexport function hashContent(content: Buffer): string {\n return crypto.createHash('md5').update(content).digest('hex');\n}\n\n/** Convenience: read file and hash in one call. */\nexport function hashFile(filePath: string): string {\n const content = fs.readFileSync(filePath);\n return hashContent(content);\n}\n","import path from 'node:path';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { securityViolation } from '../errors.js';\n\nconst DEFAULT_SECRET_PATTERNS = [\n /password/i,\n /secret/i,\n /token/i,\n /key/i,\n /credential/i,\n /api_key/i,\n /private_key/i,\n];\n\n// ─── Sensitive file detection ─────────────────────────────────────────\n// Filename/extension patterns that indicate credential or key files.\n// Matches jcodemunch-mcp's SECRET_PATTERNS for consistency across tools.\n\nconst SENSITIVE_FILE_PATTERNS = [\n // Env files (handled specially by env-parser, but still blocked from raw indexing)\n '.env', '.env.*', '*.env',\n // Certificates & keys\n '*.pem', '*.key', '*.p12', '*.pfx', '*.crt', '*.cer',\n // Keystores\n '*.keystore', '*.jks',\n // Credential files\n '*.credentials', '*.token', '*.secrets',\n 'credentials.json', 'service-account*.json',\n // SSH keys\n 'id_rsa', 'id_rsa.*', 'id_ed25519', 'id_ed25519.*', 'id_dsa', 'id_ecdsa',\n // Auth / config files with secrets\n '.htpasswd', '.netrc', '.npmrc', '.pypirc',\n // Broad wildcard (with doc exemption below)\n '*secret*',\n];\n\n// Documentation extensions where the broad *secret* glob produces false positives\n// (e.g. docs/secrets-handling.md is documentation, not a credential file).\nconst DOC_SAFE_EXTENSIONS = new Set([\n '.md', '.markdown', '.mdx', '.rst', '.txt',\n '.adoc', '.asciidoc', '.asc', '.html', '.htm', '.ipynb',\n]);\n\n// Patterns exempt from doc-extension files\nconst DOC_EXEMPT_PATTERNS = new Set(['*secret*']);\n\n/**\n * Check if a file path matches known sensitive/credential file patterns.\n * Uses filename/extension matching, not content inspection.\n */\nexport function isSensitiveFile(filePath: string): boolean {\n const name = path.basename(filePath).toLowerCase();\n const ext = path.extname(name);\n\n for (const pattern of SENSITIVE_FILE_PATTERNS) {\n // Skip broad patterns for documentation files\n if (DOC_EXEMPT_PATTERNS.has(pattern) && DOC_SAFE_EXTENSIONS.has(ext)) {\n continue;\n }\n if (matchGlob(name, pattern)) return true;\n }\n return false;\n}\n\n/** Simple glob match supporting * wildcard and .ext.* suffix patterns. */\nfunction matchGlob(name: string, pattern: string): boolean {\n // Exact match\n if (name === pattern) return true;\n\n // .env.* → matches .env.local, .env.production, etc.\n if (pattern === '.env.*' && /^\\.env\\..+$/.test(name)) return true;\n\n // id_rsa.* → matches id_rsa.pub, etc.\n if (pattern.endsWith('.*') && !pattern.startsWith('*')) {\n const prefix = pattern.slice(0, -2);\n if (name === prefix || (name.startsWith(prefix + '.') && name.length > prefix.length + 1)) {\n return true;\n }\n }\n\n // *.ext → matches any file with that extension\n if (pattern.startsWith('*.') && !pattern.includes('*', 1)) {\n const ext = pattern.slice(1); // .pem, .key, etc.\n if (name.endsWith(ext)) return true;\n }\n\n // *substring* → contains match\n if (pattern.startsWith('*') && pattern.endsWith('*') && pattern.length > 2) {\n const sub = pattern.slice(1, -1);\n if (name.includes(sub)) return true;\n }\n\n // service-account*.json → prefix + suffix\n if (pattern.includes('*') && !pattern.startsWith('*') && !pattern.endsWith('*')) {\n const starIdx = pattern.indexOf('*');\n const prefix = pattern.slice(0, starIdx);\n const suffix = pattern.slice(starIdx + 1);\n if (name.startsWith(prefix) && name.endsWith(suffix)) return true;\n }\n\n return false;\n}\n\nconst DEFAULT_MAX_FILE_SIZE = 1_048_576; // 1 MB\n\nconst ARTISAN_WHITELIST = new Set(['route:list', 'model:show', 'event:list']);\n\nexport interface SecurityConfig {\n secretPatterns?: string[];\n maxFileSizeBytes?: number;\n rootPath: string;\n}\n\nexport function validatePath(filePath: string, rootPath: string): TraceMcpResult<string> {\n const resolved = path.resolve(rootPath, filePath);\n const normalizedRoot = path.resolve(rootPath);\n\n if (!resolved.startsWith(normalizedRoot + path.sep) && resolved !== normalizedRoot) {\n return err(securityViolation(`Path traversal detected: ${filePath}`));\n }\n\n return ok(resolved);\n}\n\nexport function detectSecrets(\n content: string,\n patterns?: string[],\n): { found: boolean; matches: string[] } {\n const regexes: RegExp[] = [];\n if (patterns?.length) {\n for (const p of patterns) {\n try { regexes.push(new RegExp(p, 'i')); } catch { /* skip invalid regex */ }\n }\n } else {\n regexes.push(...DEFAULT_SECRET_PATTERNS);\n }\n\n const matches: string[] = [];\n for (const regex of regexes) {\n if (regex.test(content)) {\n matches.push(regex.source);\n }\n }\n\n return { found: matches.length > 0, matches };\n}\n\nexport function validateFileSize(\n sizeBytes: number,\n maxBytes?: number,\n): TraceMcpResult<void> {\n const limit = maxBytes ?? DEFAULT_MAX_FILE_SIZE;\n if (sizeBytes > limit) {\n return err(\n securityViolation(`File size ${sizeBytes} exceeds limit ${limit}`),\n );\n }\n return ok(undefined);\n}\n\n/** Escape a string for safe interpolation into a RegExp constructor. */\nexport function escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function validateArtisanCommand(command: string): TraceMcpResult<string> {\n if (!ARTISAN_WHITELIST.has(command)) {\n return err(\n securityViolation(\n `Artisan command '${command}' not in whitelist: [${[...ARTISAN_WHITELIST].join(', ')}]`,\n ),\n );\n }\n return ok(command);\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport fg from 'fast-glob';\nimport { logger } from '../logger.js';\n\nexport interface WorkspaceInfo {\n name: string;\n path: string; // relative to root\n}\n\n/**\n * Detect monorepo workspaces from pnpm-workspace.yaml, package.json, or composer.json.\n * Returns an empty array if no workspace config is found.\n */\nexport function detectWorkspaces(rootPath: string): WorkspaceInfo[] {\n // 1. pnpm-workspace.yaml\n const pnpmResult = detectPnpmWorkspaces(rootPath);\n if (pnpmResult.length > 0) return pnpmResult;\n\n // 2. package.json workspaces (npm/yarn)\n const npmResult = detectNpmWorkspaces(rootPath);\n if (npmResult.length > 0) return npmResult;\n\n // 3. composer.json path repositories\n const composerResult = detectComposerWorkspaces(rootPath);\n if (composerResult.length > 0) return composerResult;\n\n return [];\n}\n\nfunction detectPnpmWorkspaces(rootPath: string): WorkspaceInfo[] {\n const yamlPath = path.join(rootPath, 'pnpm-workspace.yaml');\n if (!fs.existsSync(yamlPath)) return [];\n\n try {\n const content = fs.readFileSync(yamlPath, 'utf-8');\n const parsed = parseYaml(content) as { packages?: string[] } | null;\n if (!parsed?.packages?.length) return [];\n\n return expandGlobPatterns(rootPath, parsed.packages);\n } catch (e) {\n logger.warn({ error: e }, 'Failed to parse pnpm-workspace.yaml');\n return [];\n }\n}\n\nfunction detectNpmWorkspaces(rootPath: string): WorkspaceInfo[] {\n const pkgPath = path.join(rootPath, 'package.json');\n if (!fs.existsSync(pkgPath)) return [];\n\n try {\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content) as { workspaces?: string[] | { packages?: string[] } };\n\n let patterns: string[] | undefined;\n if (Array.isArray(pkg.workspaces)) {\n patterns = pkg.workspaces;\n } else if (pkg.workspaces?.packages) {\n patterns = pkg.workspaces.packages;\n }\n\n if (!patterns?.length) return [];\n return expandGlobPatterns(rootPath, patterns);\n } catch (e) {\n logger.warn({ error: e }, 'Failed to parse package.json workspaces');\n return [];\n }\n}\n\nfunction detectComposerWorkspaces(rootPath: string): WorkspaceInfo[] {\n const composerPath = path.join(rootPath, 'composer.json');\n if (!fs.existsSync(composerPath)) return [];\n\n try {\n const content = fs.readFileSync(composerPath, 'utf-8');\n const composer = JSON.parse(content) as {\n repositories?: Array<{ type?: string; url?: string }>;\n };\n\n if (!composer.repositories?.length) return [];\n\n const pathRepos = composer.repositories.filter((r) => r.type === 'path' && r.url);\n if (pathRepos.length === 0) return [];\n\n const patterns = pathRepos.map((r) => r.url!);\n return expandGlobPatterns(rootPath, patterns);\n } catch (e) {\n logger.warn({ error: e }, 'Failed to parse composer.json repositories');\n return [];\n }\n}\n\nfunction expandGlobPatterns(rootPath: string, patterns: string[]): WorkspaceInfo[] {\n const workspaces: WorkspaceInfo[] = [];\n const seen = new Set<string>();\n\n for (const pattern of patterns) {\n // Filter out negated patterns\n if (pattern.startsWith('!')) continue;\n\n const matches = fg.sync(pattern, {\n cwd: rootPath,\n onlyDirectories: true,\n absolute: false,\n });\n\n for (const match of matches) {\n const relPath = match.replace(/\\\\/g, '/');\n if (seen.has(relPath)) continue;\n\n // Must have a package.json or composer.json to be a valid workspace\n const hasPackageJson = fs.existsSync(path.join(rootPath, relPath, 'package.json'));\n const hasComposerJson = fs.existsSync(path.join(rootPath, relPath, 'composer.json'));\n\n if (!hasPackageJson && !hasComposerJson) continue;\n\n // Derive name from package.json/composer.json\n const name = resolveWorkspaceName(rootPath, relPath);\n seen.add(relPath);\n workspaces.push({ name, path: relPath });\n }\n }\n\n return workspaces;\n}\n\nfunction resolveWorkspaceName(rootPath: string, relPath: string): string {\n // Try package.json name\n try {\n const pkgPath = path.join(rootPath, relPath, 'package.json');\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { name?: string };\n if (pkg.name) return pkg.name;\n }\n } catch { /* ignore */ }\n\n // Try composer.json name\n try {\n const composerPath = path.join(rootPath, relPath, 'composer.json');\n if (fs.existsSync(composerPath)) {\n const composer = JSON.parse(fs.readFileSync(composerPath, 'utf-8')) as { name?: string };\n if (composer.name) return composer.name;\n }\n } catch { /* ignore */ }\n\n // Fallback to directory name\n return path.basename(relPath);\n}\n","/**\n * ES Module Resolver — uses oxc-resolver to resolve import specifiers\n * following Node.js / TypeScript resolution rules.\n */\nimport path from 'node:path';\nimport { ResolverFactory } from 'oxc-resolver';\nimport type { NapiResolveOptions, TsconfigOptions } from 'oxc-resolver';\n\nexport class EsModuleResolver {\n private resolver: ResolverFactory;\n\n constructor(rootPath: string, tsconfigPath?: string) {\n const options: NapiResolveOptions = {\n conditionNames: ['import', 'require', 'node', 'default'],\n extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.json'],\n mainFields: ['module', 'main'],\n // TypeScript emits `import './foo.js'` but the source file is `foo.ts`.\n // extensionAlias maps .js → [.ts, .tsx, .js, .jsx] so the resolver finds .ts files.\n extensionAlias: {\n '.js': ['.ts', '.tsx', '.js', '.jsx'],\n '.mjs': ['.mts', '.mjs'],\n '.cjs': ['.cts', '.cjs'],\n },\n };\n\n if (tsconfigPath) {\n const tsconfig: TsconfigOptions = { configFile: tsconfigPath };\n options.tsconfig = tsconfig;\n }\n\n this.resolver = new ResolverFactory(options);\n }\n\n /** Resolve a specifier from a given source file. Returns the absolute path or undefined. */\n resolve(specifier: string, fromFile: string): string | undefined {\n const result = this.resolver.sync(path.dirname(fromFile), specifier);\n return result.path ?? undefined;\n }\n}\n","/**\n * No-op AI provider for when AI is disabled or unavailable.\n * All methods either return safe defaults or throw clear errors.\n */\nimport type { AIProvider, EmbeddingService, InferenceService } from './interfaces.js';\n\nclass FallbackEmbeddingService implements EmbeddingService {\n async embed(_text: string): Promise<number[]> {\n return [];\n }\n\n async embedBatch(_texts: string[]): Promise<number[][]> {\n return [];\n }\n\n dimensions(): number {\n return 0;\n }\n}\n\nclass FallbackInferenceService implements InferenceService {\n async generate(_prompt: string): Promise<string> {\n return '';\n }\n}\n\nexport class FallbackProvider implements AIProvider {\n async isAvailable(): Promise<boolean> {\n return false;\n }\n\n embedding(): EmbeddingService {\n return new FallbackEmbeddingService();\n }\n\n inference(): InferenceService {\n return new FallbackInferenceService();\n }\n\n fastInference(): InferenceService {\n return new FallbackInferenceService();\n }\n}\n","/**\n * Ollama AI provider — connects to a local Ollama instance via its HTTP API.\n */\nimport type { AIProvider, EmbeddingService, InferenceService } from './interfaces.js';\nimport { logger } from '../logger.js';\n\nexport interface OllamaConfig {\n baseUrl: string;\n embeddingModel: string;\n inferenceModel: string;\n fastModel: string;\n embeddingDimensions?: number;\n}\n\nclass OllamaEmbeddingService implements EmbeddingService {\n constructor(\n private baseUrl: string,\n private model: string,\n private dims: number,\n ) {}\n\n async embed(text: string): Promise<number[]> {\n const resp = await fetch(`${this.baseUrl}/api/embed`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model: this.model, input: text }),\n signal: AbortSignal.timeout(30_000),\n });\n\n if (!resp.ok) {\n throw new Error(`Ollama embed failed: ${resp.status} ${resp.statusText}`);\n }\n\n const data = (await resp.json()) as { embeddings: number[][] };\n return data.embeddings[0] ?? [];\n }\n\n async embedBatch(texts: string[]): Promise<number[][]> {\n const resp = await fetch(`${this.baseUrl}/api/embed`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model: this.model, input: texts }),\n signal: AbortSignal.timeout(30_000),\n });\n\n if (!resp.ok) {\n throw new Error(`Ollama embed batch failed: ${resp.status} ${resp.statusText}`);\n }\n\n const data = (await resp.json()) as { embeddings: number[][] };\n return data.embeddings;\n }\n\n dimensions(): number {\n return this.dims;\n }\n}\n\nclass OllamaInferenceService implements InferenceService {\n constructor(\n private baseUrl: string,\n private model: string,\n ) {}\n\n async generate(prompt: string, options?: { maxTokens?: number; temperature?: number }): Promise<string> {\n const body: Record<string, unknown> = {\n model: this.model,\n prompt,\n stream: false,\n };\n\n if (options?.maxTokens || options?.temperature !== undefined) {\n body.options = {\n ...(options.maxTokens ? { num_predict: options.maxTokens } : {}),\n ...(options.temperature !== undefined ? { temperature: options.temperature } : {}),\n };\n }\n\n const resp = await fetch(`${this.baseUrl}/api/generate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(60_000),\n });\n\n if (!resp.ok) {\n throw new Error(`Ollama generate failed: ${resp.status} ${resp.statusText}`);\n }\n\n const data = (await resp.json()) as { response: string };\n return data.response;\n }\n}\n\nexport class OllamaProvider implements AIProvider {\n private config: OllamaConfig;\n\n constructor(config: OllamaConfig) {\n this.config = config;\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n const resp = await fetch(`${this.config.baseUrl}/api/tags`, {\n signal: AbortSignal.timeout(2000),\n });\n return resp.ok;\n } catch {\n logger.debug('Ollama not available');\n return false;\n }\n }\n\n embedding(): EmbeddingService {\n return new OllamaEmbeddingService(\n this.config.baseUrl,\n this.config.embeddingModel,\n this.config.embeddingDimensions ?? 768,\n );\n }\n\n inference(): InferenceService {\n return new OllamaInferenceService(\n this.config.baseUrl,\n this.config.inferenceModel,\n );\n }\n\n fastInference(): InferenceService {\n return new OllamaInferenceService(\n this.config.baseUrl,\n this.config.fastModel,\n );\n }\n}\n","/**\n * OpenAI AI provider — connects to the OpenAI API (or any OpenAI-compatible endpoint).\n * Uses fetch directly; no SDK dependency required.\n */\nimport type { AIProvider, EmbeddingService, InferenceService } from './interfaces.js';\nimport { logger } from '../logger.js';\n\nexport interface OpenAIConfig {\n apiKey: string;\n baseUrl: string;\n embeddingModel: string;\n embeddingDimensions: number;\n inferenceModel: string;\n fastModel: string;\n}\n\nclass OpenAIEmbeddingService implements EmbeddingService {\n constructor(\n private baseUrl: string,\n private apiKey: string,\n private model: string,\n private dims: number,\n ) {}\n\n async embed(text: string): Promise<number[]> {\n const results = await this.embedBatch([text]);\n return results[0] ?? [];\n }\n\n async embedBatch(texts: string[]): Promise<number[][]> {\n const resp = await fetch(`${this.baseUrl}/embeddings`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({ model: this.model, input: texts }),\n signal: AbortSignal.timeout(30_000),\n });\n\n if (!resp.ok) {\n const body = await resp.text().catch(() => '');\n // Truncate body to avoid leaking sensitive data in error messages\n const safeBody = body.length > 200 ? body.slice(0, 200) + '…' : body;\n throw new Error(`OpenAI embeddings failed: ${resp.status} ${resp.statusText} — ${safeBody}`);\n }\n\n const data = (await resp.json()) as { data: { index: number; embedding: number[] }[] };\n // OpenAI returns data sorted by index, but let's be safe\n const result: number[][] = new Array(texts.length).fill(null);\n for (const item of data.data) {\n result[item.index] = item.embedding;\n }\n return result;\n }\n\n dimensions(): number {\n return this.dims;\n }\n}\n\nclass OpenAIInferenceService implements InferenceService {\n constructor(\n private baseUrl: string,\n private apiKey: string,\n private model: string,\n ) {}\n\n async generate(\n prompt: string,\n options?: { maxTokens?: number; temperature?: number },\n ): Promise<string> {\n const resp = await fetch(`${this.baseUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n model: this.model,\n messages: [{ role: 'user', content: prompt }],\n ...(options?.maxTokens ? { max_tokens: options.maxTokens } : {}),\n ...(options?.temperature !== undefined ? { temperature: options.temperature } : {}),\n }),\n signal: AbortSignal.timeout(60_000),\n });\n\n if (!resp.ok) {\n const body = await resp.text().catch(() => '');\n const safeBody = body.length > 200 ? body.slice(0, 200) + '…' : body;\n throw new Error(`OpenAI chat failed: ${resp.status} ${resp.statusText} — ${safeBody}`);\n }\n\n const data = (await resp.json()) as { choices: { message: { content: string } }[] };\n return data.choices[0]?.message?.content ?? '';\n }\n}\n\nexport class OpenAIProvider implements AIProvider {\n private config: OpenAIConfig;\n\n constructor(config: OpenAIConfig) {\n this.config = config;\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n const resp = await fetch(`${this.config.baseUrl}/models`, {\n headers: { Authorization: `Bearer ${this.config.apiKey}` },\n signal: AbortSignal.timeout(3000),\n });\n return resp.ok;\n } catch {\n logger.debug('OpenAI not available');\n return false;\n }\n }\n\n embedding(): EmbeddingService {\n return new OpenAIEmbeddingService(\n this.config.baseUrl,\n this.config.apiKey,\n this.config.embeddingModel,\n this.config.embeddingDimensions,\n );\n }\n\n inference(): InferenceService {\n return new OpenAIInferenceService(\n this.config.baseUrl,\n this.config.apiKey,\n this.config.inferenceModel,\n );\n }\n\n fastInference(): InferenceService {\n return new OpenAIInferenceService(\n this.config.baseUrl,\n this.config.apiKey,\n this.config.fastModel,\n );\n }\n}\n","/**\n * BLOB-based vector store using SQLite.\n * Stores embeddings as Float32Array buffers, searches via brute-force cosine similarity.\n * Fine for codebases with <10K symbols.\n */\nimport type Database from 'better-sqlite3';\nimport type { VectorStore } from './interfaces.js';\n\nconst CREATE_TABLE = `\nCREATE TABLE IF NOT EXISTS symbol_embeddings (\n symbol_id INTEGER PRIMARY KEY REFERENCES symbols(id) ON DELETE CASCADE,\n embedding BLOB NOT NULL\n)`;\n\nexport class BlobVectorStore implements VectorStore {\n constructor(private db: Database.Database) {\n this.ensureTable();\n }\n\n private ensureTable(): void {\n this.db.exec(CREATE_TABLE);\n }\n\n insert(id: number, vector: number[]): void {\n const buf = Buffer.from(new Float32Array(vector).buffer);\n this.db.prepare(\n 'INSERT OR REPLACE INTO symbol_embeddings (symbol_id, embedding) VALUES (?, ?)',\n ).run(id, buf);\n }\n\n search(query: number[], limit: number): { id: number; score: number }[] {\n const rows = this.db.prepare(\n 'SELECT symbol_id, embedding FROM symbol_embeddings',\n ).all() as { symbol_id: number; embedding: Buffer }[];\n\n if (rows.length === 0) return [];\n\n const queryArr = new Float32Array(query);\n const queryNorm = vecNorm(queryArr);\n if (queryNorm === 0) return [];\n\n const scored: { id: number; score: number }[] = [];\n\n for (const row of rows) {\n const embedding = new Float32Array(\n row.embedding.buffer,\n row.embedding.byteOffset,\n row.embedding.byteLength / 4,\n );\n const sim = cosineSimilarity(queryArr, embedding, queryNorm);\n scored.push({ id: row.symbol_id, score: sim });\n }\n\n scored.sort((a, b) => b.score - a.score);\n return scored.slice(0, limit);\n }\n\n delete(id: number): void {\n this.db.prepare('DELETE FROM symbol_embeddings WHERE symbol_id = ?').run(id);\n }\n\n count(): number {\n const row = this.db.prepare('SELECT COUNT(*) as cnt FROM symbol_embeddings').get() as { cnt: number };\n return row.cnt;\n }\n}\n\nfunction vecNorm(v: Float32Array): number {\n let sum = 0;\n for (let i = 0; i < v.length; i++) {\n sum += v[i] * v[i];\n }\n return Math.sqrt(sum);\n}\n\nfunction cosineSimilarity(a: Float32Array, b: Float32Array, aNorm?: number): number {\n if (a.length !== b.length) return 0;\n\n let dot = 0;\n let bSumSq = 0;\n\n for (let i = 0; i < a.length; i++) {\n dot += a[i] * b[i];\n bSumSq += b[i] * b[i];\n }\n\n const normA = aNorm ?? vecNorm(a);\n const normB = Math.sqrt(bSumSq);\n\n if (normA === 0 || normB === 0) return 0;\n return dot / (normA * normB);\n}\n","/**\n * Lazy background embedding indexer.\n * Finds symbols without embeddings and indexes them in batches.\n */\nimport type { Store } from '../db/store.js';\nimport type { EmbeddingService, VectorStore } from './interfaces.js';\nimport { logger } from '../logger.js';\n\nconst DEFAULT_BATCH_SIZE = 50;\n\nexport class EmbeddingPipeline {\n constructor(\n private store: Store,\n private embeddingService: EmbeddingService,\n private vectorStore: VectorStore,\n ) {}\n\n async indexSymbol(symbolId: number, text: string): Promise<void> {\n const embedding = await this.embeddingService.embed(text);\n if (embedding.length > 0) {\n this.vectorStore.insert(symbolId, embedding);\n }\n }\n\n /**\n * Find symbols that don't have embeddings yet and embed them.\n * Returns the number of newly embedded symbols.\n */\n async indexUnembedded(batchSize = DEFAULT_BATCH_SIZE): Promise<number> {\n const unembedded = this.store.db.prepare(`\n SELECT s.id, s.name, s.fqn, s.kind, s.signature, s.summary\n FROM symbols s\n LEFT JOIN symbol_embeddings se ON se.symbol_id = s.id\n WHERE se.symbol_id IS NULL\n LIMIT ?\n `).all(batchSize) as {\n id: number;\n name: string;\n fqn: string | null;\n kind: string;\n signature: string | null;\n summary: string | null;\n }[];\n\n if (unembedded.length === 0) return 0;\n\n const texts = unembedded.map((s) => buildEmbeddingText(s));\n let indexed = 0;\n\n try {\n const embeddings = await this.embeddingService.embedBatch(texts);\n for (let i = 0; i < embeddings.length; i++) {\n if (embeddings[i].length > 0) {\n this.vectorStore.insert(unembedded[i].id, embeddings[i]);\n indexed++;\n }\n }\n } catch (e) {\n logger.error({ error: e }, 'Embedding batch failed');\n }\n\n logger.debug({ indexed, total: unembedded.length }, 'Indexed unembedded symbols');\n return indexed;\n }\n\n /**\n * Re-embed all symbols (deletes existing embeddings first).\n * Returns the number of embedded symbols.\n */\n async reindexAll(): Promise<number> {\n this.store.db.exec('DELETE FROM symbol_embeddings');\n\n let total = 0;\n let batch: number;\n do {\n batch = await this.indexUnembedded(DEFAULT_BATCH_SIZE);\n total += batch;\n } while (batch > 0);\n\n return total;\n }\n}\n\nfunction buildEmbeddingText(symbol: {\n name: string;\n fqn: string | null;\n kind: string;\n signature: string | null;\n summary: string | null;\n}): string {\n const parts = [symbol.kind, symbol.fqn ?? symbol.name];\n if (symbol.signature) parts.push(symbol.signature);\n if (symbol.summary) parts.push(symbol.summary);\n return parts.join(' ');\n}\n","/**\n * Content-addressable inference cache backed by SQLite.\n * Key = sha256(model + '\\0' + prompt) → cached response.\n */\nimport type Database from 'better-sqlite3';\nimport { createHash } from 'node:crypto';\nimport { logger } from '../logger.js';\n\nexport class InferenceCache {\n constructor(private db: Database.Database) {}\n\n private cacheKey(model: string, prompt: string): string {\n return createHash('sha256').update(model + '\\0' + prompt).digest('hex');\n }\n\n get(model: string, prompt: string): string | null {\n const key = this.cacheKey(model, prompt);\n const row = this.db.prepare(\n `SELECT response FROM inference_cache\n WHERE cache_key = ?\n AND datetime(created_at, '+' || ttl_days || ' days') > datetime('now')`,\n ).get(key) as { response: string } | undefined;\n if (row) {\n logger.debug({ model, cacheKey: key.slice(0, 12) }, 'Inference cache hit');\n }\n return row?.response ?? null;\n }\n\n set(model: string, prompt: string, response: string): void {\n const key = this.cacheKey(model, prompt);\n const promptHash = createHash('sha256').update(prompt).digest('hex');\n this.db.prepare(\n `INSERT OR REPLACE INTO inference_cache (cache_key, model, prompt_hash, response, created_at, ttl_days)\n VALUES (?, ?, ?, ?, datetime('now'), 90)`,\n ).run(key, model, promptHash, response);\n }\n\n evictExpired(): number {\n const result = this.db.prepare(\n `DELETE FROM inference_cache\n WHERE datetime(created_at, '+' || ttl_days || ' days') <= datetime('now')`,\n ).run();\n const count = result.changes;\n if (count > 0) {\n logger.info({ evicted: count }, 'Evicted expired inference cache entries');\n }\n return count;\n }\n}\n","/**\n * Wraps an InferenceService with a content-addressable cache.\n * Used at index time (summarization pipeline) to avoid redundant LLM calls.\n */\nimport type { InferenceService } from './interfaces.js';\nimport type { InferenceCache } from './inference-cache.js';\n\nexport class CachedInferenceService implements InferenceService {\n constructor(\n private inner: InferenceService,\n private cache: InferenceCache,\n private model: string,\n ) {}\n\n async generate(prompt: string, options?: { maxTokens?: number; temperature?: number }): Promise<string> {\n const cached = this.cache.get(this.model, prompt);\n if (cached !== null) return cached;\n\n const response = await this.inner.generate(prompt, options);\n if (response) {\n this.cache.set(this.model, prompt, response);\n }\n return response;\n }\n}\n","/**\n * Versioned prompt templates for all AI tasks.\n * When a template changes, the prompt text changes → cache key changes → fresh generation.\n */\n\nexport interface PromptTemplate {\n version: number;\n build: (vars: Record<string, string>) => string;\n maxTokens: number;\n temperature: number;\n}\n\nexport const PROMPTS = {\n summarize_symbol: {\n version: 1,\n build: (v) => {\n const parts = [`Summarize this ${v.kind} in one concise sentence. Focus on WHAT it does, not HOW.`];\n parts.push(`Name: ${v.name}`);\n if (v.fqn) parts.push(`FQN: ${v.fqn}`);\n if (v.signature) parts.push(`Signature: ${v.signature}`);\n if (v.source) parts.push(`Source:\\n${v.source}`);\n parts.push('Summary:');\n return parts.join('\\n');\n },\n maxTokens: 100,\n temperature: 0.1,\n },\n\n explain_symbol: {\n version: 1,\n build: (v) => {\n const parts = [\n `Explain this ${v.kind} in detail. Cover: purpose, key behaviors, relationships with other code, and usage patterns.`,\n `Name: ${v.name}`,\n ];\n if (v.fqn) parts.push(`FQN: ${v.fqn}`);\n if (v.signature) parts.push(`Signature: ${v.signature}`);\n if (v.source) parts.push(`Source:\\n${v.source}`);\n if (v.context) parts.push(`Related context:\\n${v.context}`);\n parts.push('Explanation:');\n return parts.join('\\n');\n },\n maxTokens: 500,\n temperature: 0.3,\n },\n\n suggest_tests: {\n version: 1,\n build: (v) => {\n const parts = [\n 'Suggest test cases for this code. For each test, provide a description and what it should verify.',\n `Name: ${v.name}`,\n `Kind: ${v.kind}`,\n ];\n if (v.signature) parts.push(`Signature: ${v.signature}`);\n if (v.source) parts.push(`Source:\\n${v.source}`);\n if (v.dependencies) parts.push(`Dependencies:\\n${v.dependencies}`);\n parts.push('Respond in JSON: [{ \"description\": \"...\", \"verifies\": \"...\" }]');\n return parts.join('\\n');\n },\n maxTokens: 800,\n temperature: 0.3,\n },\n\n review_change: {\n version: 1,\n build: (v) => {\n const parts = [\n 'Review this code change. Identify potential issues, bugs, or improvements.',\n `File: ${v.filePath}`,\n ];\n if (v.diff) parts.push(`Diff:\\n${v.diff}`);\n if (v.blastRadius) parts.push(`Affected dependents:\\n${v.blastRadius}`);\n parts.push('Respond in JSON: { \"issues\": [{ \"severity\": \"high|medium|low\", \"description\": \"...\", \"suggestion\": \"...\" }], \"summary\": \"...\" }');\n return parts.join('\\n');\n },\n maxTokens: 800,\n temperature: 0.2,\n },\n\n explain_architecture: {\n version: 1,\n build: (v) => {\n const parts = [\n 'Analyze the architecture of this codebase scope. Describe layers, key patterns, and data flow.',\n ];\n if (v.scope) parts.push(`Scope: ${v.scope}`);\n if (v.context) parts.push(`Key symbols and structure:\\n${v.context}`);\n parts.push('Respond in JSON: { \"overview\": \"...\", \"layers\": [\"...\"], \"key_patterns\": [\"...\"], \"data_flow\": [\"...\"] }');\n return parts.join('\\n');\n },\n maxTokens: 1000,\n temperature: 0.3,\n },\n\n rerank: {\n version: 1,\n build: (v) => {\n return `Rate the relevance of each document to the query on a scale of 0-10.\nQuery: ${v.query}\n\nDocuments:\n${v.documents}\n\nRespond with one score per line, in order: just the number, nothing else.`;\n },\n maxTokens: 200,\n temperature: 0.0,\n },\n} satisfies Record<string, PromptTemplate>;\n","/**\n * AI-powered summarization pipeline.\n * Runs after indexing to populate the symbols.summary column using the fast inference model.\n * Uses CachedInferenceService to avoid redundant LLM calls across re-indexes.\n */\nimport type { InferenceService } from './interfaces.js';\nimport type { Store } from '../db/store.js';\nimport { PROMPTS } from './prompts.js';\nimport { logger } from '../logger.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface SummarizationConfig {\n batchSize: number;\n kinds: string[];\n}\n\nconst MAX_SOURCE_LINES = 80;\n\nexport class SummarizationPipeline {\n constructor(\n private store: Store,\n private inferenceService: InferenceService,\n private rootPath: string,\n private config: SummarizationConfig,\n ) {}\n\n async summarizeUnsummarized(): Promise<number> {\n let totalSummarized = 0;\n let batch: ReturnType<Store['getUnsummarizedSymbols']>;\n\n do {\n batch = this.store.getUnsummarizedSymbols(this.config.kinds, this.config.batchSize);\n if (batch.length === 0) break;\n\n const results = await this.summarizeBatch(batch);\n for (const { id, summary } of results) {\n this.store.updateSymbolSummary(id, summary);\n totalSummarized++;\n }\n\n logger.debug({ batch: batch.length, total: totalSummarized }, 'Summarization batch complete');\n } while (batch.length === this.config.batchSize);\n\n if (totalSummarized > 0) {\n logger.info({ totalSummarized }, 'Symbol summarization complete');\n }\n return totalSummarized;\n }\n\n private async summarizeBatch(\n symbols: ReturnType<Store['getUnsummarizedSymbols']>,\n ): Promise<{ id: number; summary: string }[]> {\n const results: { id: number; summary: string }[] = [];\n const template = PROMPTS.summarize_symbol;\n\n for (const sym of symbols) {\n try {\n const source = this.readSource(sym.file_path, sym.byte_start, sym.byte_end);\n const prompt = template.build({\n kind: sym.kind,\n name: sym.name,\n fqn: sym.fqn ?? '',\n signature: sym.signature ?? '',\n source: source ?? '',\n });\n\n const summary = await this.inferenceService.generate(prompt, {\n maxTokens: template.maxTokens,\n temperature: template.temperature,\n });\n\n const cleaned = summary.trim();\n if (cleaned) {\n results.push({ id: sym.id, summary: cleaned });\n }\n } catch (e) {\n logger.warn({ symbolId: sym.id, name: sym.name, error: e }, 'Failed to summarize symbol');\n }\n }\n\n return results;\n }\n\n private readSource(filePath: string, byteStart: number, byteEnd: number): string | null {\n try {\n const absPath = path.resolve(this.rootPath, filePath);\n const content = fs.readFileSync(absPath, 'utf-8');\n const slice = content.slice(byteStart, byteEnd);\n const lines = slice.split('\\n');\n if (lines.length > MAX_SOURCE_LINES) {\n return lines.slice(0, MAX_SOURCE_LINES).join('\\n') + '\\n// ... truncated';\n }\n return slice;\n } catch {\n return null;\n }\n }\n}\n","/**\n * LLM-based reranker — uses a fast inference model to re-score search results.\n * Falls back to original order on parse failure.\n */\nimport type { InferenceService, RerankerService } from './interfaces.js';\nimport { PROMPTS } from './prompts.js';\nimport { logger } from '../logger.js';\n\nexport class LLMReranker implements RerankerService {\n constructor(private inference: InferenceService) {}\n\n async rerank(\n query: string,\n documents: { id: number; text: string }[],\n topK: number,\n ): Promise<{ id: number; score: number }[]> {\n if (documents.length === 0) return [];\n if (documents.length <= 1) return documents.map((d) => ({ id: d.id, score: 1 }));\n\n try {\n const docsText = documents\n .map((d, i) => `[${i + 1}] ${d.text.slice(0, 200)}`)\n .join('\\n');\n\n const prompt = PROMPTS.rerank.build({\n query,\n documents: docsText,\n });\n\n const response = await this.inference.generate(prompt, {\n maxTokens: PROMPTS.rerank.maxTokens,\n temperature: PROMPTS.rerank.temperature,\n });\n\n const scores = this.parseScores(response, documents.length);\n if (!scores) {\n logger.debug('Reranker: failed to parse scores, keeping original order');\n return documents.slice(0, topK).map((d, i) => ({\n id: d.id,\n score: documents.length - i,\n }));\n }\n\n const scored = documents.map((d, i) => ({\n id: d.id,\n score: scores[i] ?? 0,\n }));\n\n scored.sort((a, b) => b.score - a.score);\n return scored.slice(0, topK);\n } catch (e) {\n logger.warn({ error: e }, 'Reranker failed, keeping original order');\n return documents.slice(0, topK).map((d, i) => ({\n id: d.id,\n score: documents.length - i,\n }));\n }\n }\n\n private parseScores(response: string, expectedCount: number): number[] | null {\n const lines = response.trim().split('\\n').map((l) => l.trim()).filter(Boolean);\n const scores: number[] = [];\n\n for (const line of lines) {\n const match = line.match(/(\\d+(?:\\.\\d+)?)/);\n if (match) {\n scores.push(parseFloat(match[1]));\n }\n if (scores.length >= expectedCount) break;\n }\n\n if (scores.length !== expectedCount) return null;\n return scores;\n }\n}\n","/**\n * AI layer factory — creates the appropriate provider based on config.\n * Returns FallbackProvider when AI is disabled.\n */\nimport type { TraceMcpConfig } from '../config.js';\nimport type { AIProvider } from './interfaces.js';\nimport { FallbackProvider } from './fallback.js';\nimport { OllamaProvider } from './ollama.js';\nimport { OpenAIProvider } from './openai.js';\nimport { logger } from '../logger.js';\n\nexport function createAIProvider(config: TraceMcpConfig): AIProvider {\n if (!config.ai?.enabled) {\n return new FallbackProvider();\n }\n\n if (config.ai.provider === 'openai') {\n const apiKey = config.ai.api_key ?? process.env.OPENAI_API_KEY ?? '';\n if (!apiKey) {\n logger.warn('OpenAI provider selected but no api_key configured — falling back to FallbackProvider');\n return new FallbackProvider();\n }\n return new OpenAIProvider({\n apiKey,\n baseUrl: config.ai.base_url ?? 'https://api.openai.com/v1',\n embeddingModel: config.ai.embedding_model ?? 'text-embedding-3-small',\n embeddingDimensions: config.ai.embedding_dimensions ?? 1536,\n inferenceModel: config.ai.inference_model ?? 'gpt-4o-mini',\n fastModel: config.ai.fast_model ?? 'gpt-4o-mini',\n });\n }\n\n if (config.ai.provider === 'ollama') {\n return new OllamaProvider({\n baseUrl: config.ai.base_url ?? 'http://localhost:11434',\n embeddingModel: config.ai.embedding_model ?? 'nomic-embed-text',\n inferenceModel: config.ai.inference_model ?? 'qwen2.5-coder:7b',\n fastModel: config.ai.fast_model ?? 'qwen2.5-coder:1.5b',\n embeddingDimensions: config.ai.embedding_dimensions,\n });\n }\n\n return new FallbackProvider();\n}\n\nexport type { AIProvider, EmbeddingService, InferenceService, VectorStore, RerankerService } from './interfaces.js';\nexport { FallbackProvider } from './fallback.js';\nexport { OllamaProvider } from './ollama.js';\nexport { OpenAIProvider } from './openai.js';\nexport { BlobVectorStore } from './vector-store.js';\nexport { hybridSearch } from './search.js';\nexport { EmbeddingPipeline } from './embedding-pipeline.js';\nexport { InferenceCache } from './inference-cache.js';\nexport { CachedInferenceService } from './cached-inference.js';\nexport { SummarizationPipeline } from './summarization-pipeline.js';\nexport { PROMPTS } from './prompts.js';\nexport { LLMReranker } from './reranker.js';\nexport type { PromptTemplate } from './prompts.js';\n","/**\n * AI-powered MCP tools — require AI to be enabled.\n * Each tool gracefully returns an error message when AI is disabled.\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport type { Store, SymbolRow, FileRow } from '../db/store.js';\nimport type { InferenceService, EmbeddingService, VectorStore, RerankerService } from '../ai/interfaces.js';\nimport { PROMPTS } from '../ai/prompts.js';\nimport { readByteRange } from '../utils/source-reader.js';\nimport { assembleStructuredContext, renderStructuredContext } from '../scoring/structured-assembly.js';\nimport type { ContextItem } from '../scoring/assembly.js';\nimport { getChangeImpact } from './impact.js';\nimport path from 'node:path';\n\ninterface AIToolsContext {\n store: Store;\n smartInference: InferenceService;\n fastInference: InferenceService;\n embeddingService: EmbeddingService | null;\n vectorStore: VectorStore | null;\n reranker: RerankerService | null;\n projectRoot: string;\n}\n\nfunction j(value: unknown): string {\n return JSON.stringify(value);\n}\n\nfunction symbolToContextItem(sym: SymbolRow, file: FileRow, projectRoot: string, score = 1): ContextItem {\n const source = readSourceSafe(file.path, sym.byte_start, sym.byte_end, projectRoot);\n return {\n id: sym.symbol_id,\n score,\n source: source ?? undefined,\n signature: sym.signature ?? undefined,\n metadata: `${sym.kind} ${sym.fqn ?? sym.name} — ${file.path}`,\n };\n}\n\nfunction readSourceSafe(filePath: string, byteStart: number, byteEnd: number, projectRoot: string): string | null {\n try {\n const absPath = path.resolve(projectRoot, filePath);\n return readByteRange(absPath, byteStart, byteEnd);\n } catch {\n return null;\n }\n}\n\nfunction resolveSymbol(store: Store, opts: { symbolId?: string; fqn?: string }): { sym: SymbolRow; file: FileRow } | null {\n let sym: SymbolRow | undefined;\n if (opts.symbolId) {\n sym = store.getSymbolBySymbolId(opts.symbolId);\n } else if (opts.fqn) {\n sym = store.getSymbolByFqn(opts.fqn);\n }\n if (!sym) return null;\n const file = store.getFileById(sym.file_id);\n if (!file) return null;\n return { sym, file };\n}\n\nfunction gatherRelatedSymbols(\n store: Store,\n sym: SymbolRow,\n projectRoot: string,\n): { dependencies: ContextItem[]; callers: ContextItem[]; typeContext: ContextItem[] } {\n const dependencies: ContextItem[] = [];\n const callers: ContextItem[] = [];\n const typeContext: ContextItem[] = [];\n\n const symNodeId = store.getNodeId('symbol', sym.id);\n if (!symNodeId) return { dependencies, callers, typeContext };\n\n // Outgoing edges = dependencies\n const outEdges = store.getOutgoingEdges(symNodeId);\n for (const edge of outEdges.slice(0, 10)) {\n const ref = store.getNodeRef(edge.target_node_id);\n if (!ref || ref.nodeType !== 'symbol') continue;\n const depSym = store.getSymbolById(ref.refId);\n if (!depSym) continue;\n const depFile = store.getFileById(depSym.file_id);\n if (!depFile) continue;\n dependencies.push(symbolToContextItem(depSym, depFile, projectRoot, 0.5));\n }\n\n // Incoming edges = callers\n const inEdges = store.getIncomingEdges(symNodeId);\n for (const edge of inEdges.slice(0, 10)) {\n const ref = store.getNodeRef(edge.source_node_id);\n if (!ref || ref.nodeType !== 'symbol') continue;\n const callerSym = store.getSymbolById(ref.refId);\n if (!callerSym) continue;\n const callerFile = store.getFileById(callerSym.file_id);\n if (!callerFile) continue;\n callers.push(symbolToContextItem(callerSym, callerFile, projectRoot, 0.3));\n }\n\n // Type hierarchy\n if (sym.metadata) {\n try {\n const meta = JSON.parse(sym.metadata);\n const parents = [...(meta.extends ? [meta.extends].flat() : []), ...(meta.implements ?? [])];\n for (const parentName of parents.slice(0, 5)) {\n const parentSym = store.getSymbolByName(parentName);\n if (!parentSym) continue;\n const parentFile = store.getFileById(parentSym.file_id);\n if (!parentFile) continue;\n typeContext.push(symbolToContextItem(parentSym, parentFile, projectRoot, 0.4));\n }\n } catch { /* ignore parse errors */ }\n }\n\n return { dependencies, callers, typeContext };\n}\n\nexport function registerAITools(\n server: McpServer,\n ctx: AIToolsContext,\n): void {\n const { store, smartInference, embeddingService, vectorStore, reranker, projectRoot } = ctx;\n\n // ─── explain_symbol ──────────────────────────────────────\n server.tool(\n 'explain_symbol',\n 'Explain a symbol in detail using AI — purpose, behavior, relationships, usage patterns',\n {\n symbol_id: z.string().optional().describe('Symbol ID (e.g. src/auth.ts::AuthService#class)'),\n fqn: z.string().optional().describe('Fully qualified name'),\n },\n async ({ symbol_id, fqn }) => {\n const resolved = resolveSymbol(store, { symbolId: symbol_id, fqn });\n if (!resolved) {\n return { content: [{ type: 'text', text: j({ error: 'Symbol not found' }) }], isError: true };\n }\n const { sym, file } = resolved;\n const primary = [symbolToContextItem(sym, file, projectRoot)];\n const related = gatherRelatedSymbols(store, sym, projectRoot);\n\n const structured = assembleStructuredContext({\n primary,\n dependencies: related.dependencies,\n callers: related.callers,\n typeContext: related.typeContext,\n totalBudget: 4000,\n });\n\n const contextStr = renderStructuredContext(structured);\n const prompt = PROMPTS.explain_symbol.build({\n kind: sym.kind,\n name: sym.name,\n fqn: sym.fqn ?? '',\n signature: sym.signature ?? '',\n source: primary[0].source ?? '',\n context: contextStr,\n });\n\n const explanation = await smartInference.generate(prompt, {\n maxTokens: PROMPTS.explain_symbol.maxTokens,\n temperature: PROMPTS.explain_symbol.temperature,\n });\n\n return {\n content: [{\n type: 'text',\n text: j({\n symbol_id: sym.symbol_id,\n name: sym.name,\n kind: sym.kind,\n file: file.path,\n explanation,\n related_symbols: [\n ...related.dependencies.map((d) => d.id),\n ...related.callers.map((c) => c.id),\n ...related.typeContext.map((t) => t.id),\n ],\n }),\n }],\n };\n },\n );\n\n // ─── suggest_tests ───────────────────────────────────────\n server.tool(\n 'suggest_tests',\n 'Suggest test cases for a symbol using AI',\n {\n symbol_id: z.string().optional().describe('Symbol ID'),\n fqn: z.string().optional().describe('Fully qualified name'),\n },\n async ({ symbol_id, fqn }) => {\n const resolved = resolveSymbol(store, { symbolId: symbol_id, fqn });\n if (!resolved) {\n return { content: [{ type: 'text', text: j({ error: 'Symbol not found' }) }], isError: true };\n }\n const { sym, file } = resolved;\n const source = readSourceSafe(file.path, sym.byte_start, sym.byte_end, projectRoot);\n const related = gatherRelatedSymbols(store, sym, projectRoot);\n\n const depsStr = related.dependencies.map((d) => d.metadata).join('\\n');\n\n const prompt = PROMPTS.suggest_tests.build({\n kind: sym.kind,\n name: sym.name,\n signature: sym.signature ?? '',\n source: source ?? '',\n dependencies: depsStr,\n });\n\n const response = await smartInference.generate(prompt, {\n maxTokens: PROMPTS.suggest_tests.maxTokens,\n temperature: PROMPTS.suggest_tests.temperature,\n });\n\n let suggestions: unknown;\n try {\n suggestions = JSON.parse(response);\n } catch {\n suggestions = [{ description: response, verifies: 'See description' }];\n }\n\n return {\n content: [{\n type: 'text',\n text: j({\n symbol_id: sym.symbol_id,\n name: sym.name,\n suggestions,\n }),\n }],\n };\n },\n );\n\n // ─── review_change ───────────────────────────────────────\n server.tool(\n 'review_change',\n 'AI-powered review of a file change — identify issues, risks, and suggestions',\n {\n file_path: z.string().describe('File path relative to project root'),\n diff: z.string().optional().describe('Git diff content (if not provided, reviews full file)'),\n },\n async ({ file_path, diff }) => {\n const impactResult = getChangeImpact(store, { filePath: file_path });\n const blastRadius = impactResult.isOk()\n ? impactResult.value.dependents.map((d) => `${d.edgeType}: ${d.path}`).join('\\n')\n : '';\n\n const prompt = PROMPTS.review_change.build({\n filePath: file_path,\n diff: diff ?? '',\n blastRadius,\n });\n\n const response = await smartInference.generate(prompt, {\n maxTokens: PROMPTS.review_change.maxTokens,\n temperature: PROMPTS.review_change.temperature,\n });\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(response);\n } catch {\n parsed = { issues: [], summary: response };\n }\n\n return { content: [{ type: 'text', text: j(parsed) }] };\n },\n );\n\n // ─── find_similar ────────────────────────────────────────\n server.tool(\n 'find_similar',\n 'Find semantically similar symbols using vector search + optional AI reranking',\n {\n symbol_id: z.string().optional().describe('Symbol ID to find similar code to'),\n query: z.string().optional().describe('Free-text query (used if no symbol_id)'),\n limit: z.number().int().min(1).max(50).optional().describe('Max results (default 10)'),\n },\n async ({ symbol_id, query, limit: maxResults }) => {\n const resultLimit = maxResults ?? 10;\n\n if (!embeddingService || !vectorStore) {\n return { content: [{ type: 'text', text: j({ error: 'Vector search requires AI embeddings to be enabled' }) }], isError: true };\n }\n\n let queryText: string;\n if (symbol_id) {\n const sym = store.getSymbolBySymbolId(symbol_id);\n if (!sym) {\n return { content: [{ type: 'text', text: j({ error: 'Symbol not found' }) }], isError: true };\n }\n queryText = [sym.kind, sym.fqn ?? sym.name, sym.signature ?? '', sym.summary ?? ''].join(' ');\n } else if (query) {\n queryText = query;\n } else {\n return { content: [{ type: 'text', text: j({ error: 'Provide symbol_id or query' }) }], isError: true };\n }\n\n const embedding = await embeddingService.embed(queryText);\n if (embedding.length === 0) {\n return { content: [{ type: 'text', text: j({ results: [] }) }] };\n }\n\n let vectorResults = vectorStore.search(embedding, resultLimit * 3);\n\n // Exclude the source symbol from results\n if (symbol_id) {\n const srcSym = store.getSymbolBySymbolId(symbol_id);\n if (srcSym) {\n vectorResults = vectorResults.filter((r) => r.id !== srcSym.id);\n }\n }\n\n // Optional reranking\n if (reranker && vectorResults.length > 1) {\n const docs = vectorResults.map((r) => {\n const sym = store.getSymbolById(r.id);\n return { id: r.id, text: sym ? `${sym.kind} ${sym.fqn ?? sym.name} ${sym.signature ?? ''}` : '' };\n });\n try {\n const reranked = await reranker.rerank(queryText, docs, resultLimit);\n vectorResults = reranked.map((r) => ({ id: r.id, score: r.score }));\n } catch { /* keep original order */ }\n }\n\n const results = vectorResults.slice(0, resultLimit).map((r) => {\n const sym = store.getSymbolById(r.id);\n const file = sym ? store.getFileById(sym.file_id) : undefined;\n return {\n symbol_id: sym?.symbol_id,\n name: sym?.name,\n kind: sym?.kind,\n fqn: sym?.fqn,\n file: file?.path,\n similarity: Math.round(r.score * 1000) / 1000,\n summary: sym?.summary ?? null,\n };\n }).filter((r) => r.symbol_id);\n\n return { content: [{ type: 'text', text: j({ results }) }] };\n },\n );\n\n // ─── explain_architecture ────────────────────────────────\n server.tool(\n 'explain_architecture',\n 'AI-powered architecture analysis — layers, patterns, and data flow',\n {\n scope: z.string().optional().describe('Scope to analyze (e.g. \"authentication\", \"data layer\", or empty for full project)'),\n token_budget: z.number().int().min(500).max(16000).optional().describe('Token budget for context (default 6000)'),\n },\n async ({ scope, token_budget }) => {\n const budget = token_budget ?? 6000;\n\n // Gather key symbols via FTS if scope provided, otherwise top symbols by kind\n const symbols: ContextItem[] = [];\n\n if (scope) {\n // Use FTS to find relevant symbols\n const ftsQuery = scope.split(/\\s+/).map((t) => `\"${t}\"`).join(' OR ');\n const ftsResults = store.db.prepare(`\n SELECT s.*, f.path as file_path\n FROM symbols_fts fts\n JOIN symbols s ON s.id = fts.rowid\n JOIN files f ON f.id = s.file_id\n WHERE symbols_fts MATCH ?\n ORDER BY rank\n LIMIT 30\n `).all(ftsQuery) as (SymbolRow & { file_path: string })[];\n\n for (const row of ftsResults) {\n const file = store.getFileById(row.file_id);\n if (!file) continue;\n symbols.push(symbolToContextItem(row, file, projectRoot, 0.5));\n }\n } else {\n // Get top classes/interfaces as architectural anchors\n const topSymbols = store.db.prepare(`\n SELECT s.*, f.path as file_path\n FROM symbols s\n JOIN files f ON f.id = s.file_id\n WHERE s.kind IN ('class', 'interface', 'trait')\n LIMIT 30\n `).all() as (SymbolRow & { file_path: string })[];\n\n for (const row of topSymbols) {\n const file = store.getFileById(row.file_id);\n if (!file) continue;\n symbols.push(symbolToContextItem(row, file, projectRoot, 0.5));\n }\n }\n\n const assembled = assembleStructuredContext({\n primary: symbols,\n dependencies: [],\n callers: [],\n typeContext: [],\n totalBudget: budget,\n budgetWeights: { primary: 1.0, dependencies: 0, callers: 0, typeContext: 0 },\n });\n\n const contextStr = renderStructuredContext(assembled);\n const prompt = PROMPTS.explain_architecture.build({\n scope: scope ?? 'full project',\n context: contextStr,\n });\n\n const response = await smartInference.generate(prompt, {\n maxTokens: PROMPTS.explain_architecture.maxTokens,\n temperature: PROMPTS.explain_architecture.temperature,\n });\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(response);\n } catch {\n parsed = { overview: response, layers: [], key_patterns: [], data_flow: [] };\n }\n\n return { content: [{ type: 'text', text: j(parsed) }] };\n },\n );\n}\n","/**\n * Structured context assembly for AI tools.\n * Groups items by role (primary, dependencies, callers, type context)\n * and allocates token budget proportionally.\n */\nimport { assembleContext, type ContextItem, type AssembledItem } from './assembly.js';\n\nexport interface StructuredContextRequest {\n primary: ContextItem[];\n dependencies: ContextItem[];\n callers: ContextItem[];\n typeContext: ContextItem[];\n totalBudget: number;\n budgetWeights?: { primary: number; dependencies: number; callers: number; typeContext: number };\n}\n\nexport interface StructuredContextResult {\n primary: AssembledItem[];\n dependencies: AssembledItem[];\n callers: AssembledItem[];\n typeContext: AssembledItem[];\n totalTokens: number;\n truncated: boolean;\n}\n\nconst DEFAULT_WEIGHTS = { primary: 0.4, dependencies: 0.3, callers: 0.2, typeContext: 0.1 };\n\nexport function assembleStructuredContext(request: StructuredContextRequest): StructuredContextResult {\n const weights = request.budgetWeights ?? DEFAULT_WEIGHTS;\n const budget = request.totalBudget;\n\n const primaryResult = assembleContext(request.primary, Math.floor(budget * weights.primary));\n const depsResult = assembleContext(request.dependencies, Math.floor(budget * weights.dependencies));\n const callersResult = assembleContext(request.callers, Math.floor(budget * weights.callers));\n const typeResult = assembleContext(request.typeContext, Math.floor(budget * weights.typeContext));\n\n return {\n primary: primaryResult.items,\n dependencies: depsResult.items,\n callers: callersResult.items,\n typeContext: typeResult.items,\n totalTokens: primaryResult.totalTokens + depsResult.totalTokens + callersResult.totalTokens + typeResult.totalTokens,\n truncated: primaryResult.truncated || depsResult.truncated || callersResult.truncated || typeResult.truncated,\n };\n}\n\n/**\n * Render structured context into a flat string for LLM prompts.\n */\nexport function renderStructuredContext(result: StructuredContextResult): string {\n const sections: string[] = [];\n\n if (result.primary.length > 0) {\n sections.push('=== Primary Symbol ===\\n' + result.primary.map((i) => i.content).join('\\n\\n'));\n }\n if (result.dependencies.length > 0) {\n sections.push('=== Dependencies ===\\n' + result.dependencies.map((i) => i.content).join('\\n\\n'));\n }\n if (result.callers.length > 0) {\n sections.push('=== Callers ===\\n' + result.callers.map((i) => i.content).join('\\n\\n'));\n }\n if (result.typeContext.length > 0) {\n sections.push('=== Type Hierarchy ===\\n' + result.typeContext.map((i) => i.content).join('\\n\\n'));\n }\n\n return sections.join('\\n\\n');\n}\n","/**\n * get_middleware_chain — Trace middleware for a given route URL.\n *\n * Express: app-level -> router-level -> route-level middleware.\n * NestJS: guards -> pipes -> interceptors -> filters.\n * Flask: global before_request -> blueprint before_request -> route.\n * FastAPI: app middleware -> router middleware -> Depends().\n * Django: settings.MIDDLEWARE -> view decorators.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { Store } from '../db/store.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { escapeRegExp } from '../utils/security.js';\nimport { notFound } from '../errors.js';\n\nexport interface MiddlewareEntry {\n name: string;\n scope: 'global' | 'router' | 'route' | 'guard' | 'pipe' | 'interceptor' | 'filter'\n | 'before_request' | 'after_request' | 'error_handler' | 'depends' | 'middleware' | 'view_decorator';\n path?: string;\n file?: string;\n}\n\nexport interface MiddlewareChainResult {\n url: string;\n framework: 'express' | 'nestjs' | 'flask' | 'fastapi' | 'django' | 'unknown';\n chain: MiddlewareEntry[];\n}\n\n/**\n * Build middleware chain for a given URL.\n * Inspects indexed routes and file content to trace middleware layers.\n */\nexport function getMiddlewareChain(\n store: Store,\n rootPath: string,\n url: string,\n): TraceMcpResult<MiddlewareChainResult> {\n const allRoutes = store.getAllRoutes();\n\n // Find matching route\n const matchingRoute = allRoutes.find((r) => {\n const pattern = r.uri\n .replace(/:[^/]+/g, '\\0PARAM\\0')\n .replace(/\\{[^}]+\\}/g, '\\0PARAM\\0')\n .replace(/<[^>]+>/g, '\\0PARAM\\0') // Django/Flask: <int:pk>\n .split('\\0PARAM\\0')\n .map(escapeRegExp)\n .join('[^/]+');\n return new RegExp(`^${pattern}$`).test(url) || r.uri === url;\n });\n\n if (!matchingRoute) {\n return err(notFound(url, ['No matching route found. Run reindex first.']));\n }\n\n const chain: MiddlewareEntry[] = [];\n const allFiles = store.getAllFiles();\n\n // Detect framework\n const framework = detectFramework(allFiles);\n\n if (framework === 'express') {\n buildExpressChain(store, rootPath, url, allFiles, chain);\n } else if (framework === 'nestjs') {\n buildNestChain(store, rootPath, matchingRoute, allFiles, chain);\n } else if (framework === 'flask') {\n buildFlaskChain(store, rootPath, url, allFiles, chain);\n } else if (framework === 'fastapi') {\n buildFastAPIChain(store, rootPath, url, allFiles, chain);\n } else if (framework === 'django') {\n buildDjangoChain(store, rootPath, allFiles, chain);\n }\n\n // Add route-level middleware from the route itself\n if (matchingRoute.middleware) {\n try {\n const parsed = JSON.parse(matchingRoute.middleware) as { middleware?: string[] };\n for (const mw of parsed.middleware ?? []) {\n chain.push({ name: mw, scope: 'route', path: matchingRoute.uri });\n }\n } catch {\n // ignore malformed middleware JSON\n }\n }\n\n return ok({ url, framework, chain });\n}\n\ntype FileInfo = { id: number; path: string; framework_role: string | null };\n\nfunction detectFramework(allFiles: FileInfo[]): MiddlewareChainResult['framework'] {\n for (const f of allFiles) {\n const role = f.framework_role;\n if (!role) continue;\n if (role.startsWith('nest_')) return 'nestjs';\n if (role.startsWith('express_')) return 'express';\n if (role.startsWith('flask_')) return 'flask';\n if (role.startsWith('fastapi_')) return 'fastapi';\n if (role.startsWith('django_') || role === 'url_config') return 'django';\n }\n return 'unknown';\n}\n\nfunction readSource(rootPath: string, filePath: string): string | undefined {\n try {\n return fs.readFileSync(path.resolve(rootPath, filePath), 'utf-8');\n } catch {\n return undefined;\n }\n}\n\n// ─── Express ──────────────────────────────────────────────────\n\nfunction buildExpressChain(\n store: Store,\n rootPath: string,\n url: string,\n allFiles: FileInfo[],\n chain: MiddlewareEntry[],\n): void {\n const GLOBAL_MW_RE = /(?:app|router)\\s*\\.\\s*use\\s*\\(\\s*([A-Za-z][\\w.]*(?:\\s*\\(\\s*[^)]*\\))?)\\s*[,)]/g;\n const PATH_MW_RE = /(?:app|router)\\s*\\.\\s*use\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*,\\s*([A-Za-z][\\w.]*)/g;\n\n for (const file of allFiles) {\n if (file.framework_role !== 'express_router' && file.framework_role !== 'express_middleware') continue;\n const source = readSource(rootPath, file.path);\n if (!source) continue;\n\n let match: RegExpExecArray | null;\n const globalRe = new RegExp(GLOBAL_MW_RE.source, 'g');\n while ((match = globalRe.exec(source)) !== null) {\n const name = match[1].trim();\n if (/^['\"`]/.test(name)) continue;\n chain.push({ name, scope: 'global', file: file.path });\n }\n\n const pathRe = new RegExp(PATH_MW_RE.source, 'g');\n while ((match = pathRe.exec(source)) !== null) {\n const mwPath = match[1];\n if (url.startsWith(mwPath)) {\n chain.push({ name: match[2], scope: 'router', path: mwPath, file: file.path });\n }\n }\n }\n}\n\n// ─── NestJS ───────────────────────────────────────────────────\n\nfunction buildNestChain(\n store: Store,\n rootPath: string,\n route: { uri: string; file_id: number | null },\n allFiles: FileInfo[],\n chain: MiddlewareEntry[],\n): void {\n const GUARDS_RE = /@UseGuards\\(\\s*([^)]+)\\s*\\)/g;\n const PIPES_RE = /@UsePipes\\(\\s*([^)]+)\\s*\\)/g;\n const INTERCEPTORS_RE = /@UseInterceptors\\(\\s*([^)]+)\\s*\\)/g;\n const FILTERS_RE = /@UseFilters\\(\\s*([^)]+)\\s*\\)/g;\n\n const controllerFiles = allFiles.filter((f) => f.framework_role === 'nest_controller');\n\n for (const file of controllerFiles) {\n const source = readSource(rootPath, file.path);\n if (!source) continue;\n\n const extractDecorators = (regex: RegExp, scope: MiddlewareEntry['scope']) => {\n const re = new RegExp(regex.source, 'g');\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n const items = m[1].split(',').map((s) => s.trim()).filter(Boolean);\n for (const item of items) {\n chain.push({ name: item, scope, file: file.path });\n }\n }\n };\n\n extractDecorators(GUARDS_RE, 'guard');\n extractDecorators(PIPES_RE, 'pipe');\n extractDecorators(INTERCEPTORS_RE, 'interceptor');\n extractDecorators(FILTERS_RE, 'filter');\n }\n}\n\n// ─── Flask ────────────────────────────────────────────────────\n\nfunction buildFlaskChain(\n store: Store,\n rootPath: string,\n url: string,\n allFiles: FileInfo[],\n chain: MiddlewareEntry[],\n): void {\n // Leverage existing flask_before_request and flask_error_handler edges\n const beforeEdges = store.getEdgesByType('flask_before_request');\n for (const edge of beforeEdges) {\n const ref = store.getNodeRef(edge.source_node_id);\n if (!ref) continue;\n let filePath = '';\n let name = 'before_request';\n if (ref.nodeType === 'symbol') {\n const sym = store.getSymbolById(ref.refId);\n if (sym) {\n name = sym.name;\n const f = store.getFileById(sym.file_id);\n filePath = f?.path ?? '';\n }\n }\n chain.push({ name, scope: 'before_request', file: filePath });\n }\n\n const errorEdges = store.getEdgesByType('flask_error_handler');\n for (const edge of errorEdges) {\n const ref = store.getNodeRef(edge.source_node_id);\n if (!ref) continue;\n let name = 'error_handler';\n let filePath = '';\n if (ref.nodeType === 'symbol') {\n const sym = store.getSymbolById(ref.refId);\n if (sym) {\n name = sym.name;\n const f = store.getFileById(sym.file_id);\n filePath = f?.path ?? '';\n }\n }\n chain.push({ name, scope: 'error_handler', file: filePath });\n }\n\n // Also scan for route-level decorators in matching route files\n for (const file of allFiles) {\n if (file.framework_role !== 'flask_routes') continue;\n const source = readSource(rootPath, file.path);\n if (!source) continue;\n\n // @login_required, @auth.login_required etc. before route handlers\n const decoratorRe = /@([\\w.]+)\\s*(?:\\([^)]*\\))?\\s*\\n\\s*(?:@\\w[\\w.]*\\s*(?:\\([^)]*\\))?\\s*\\n\\s*)*def\\s+\\w+/g;\n let m: RegExpExecArray | null;\n while ((m = decoratorRe.exec(source)) !== null) {\n const dec = m[1];\n if (['app.route', 'bp.route', 'blueprint.route'].some((r) => dec.includes(r))) continue;\n if (dec.includes('route')) continue;\n chain.push({ name: `@${dec}`, scope: 'view_decorator', file: file.path });\n }\n }\n}\n\n// ─── FastAPI ──────────────────────────────────────────────────\n\nfunction buildFastAPIChain(\n store: Store,\n rootPath: string,\n url: string,\n allFiles: FileInfo[],\n chain: MiddlewareEntry[],\n): void {\n // Scan for app.add_middleware() calls\n for (const file of allFiles) {\n if (file.framework_role !== 'fastapi_routes' && file.framework_role !== 'fastapi_app') continue;\n const source = readSource(rootPath, file.path);\n if (!source) continue;\n\n // app.add_middleware(CORSMiddleware, ...) or app.add_middleware(Middleware)\n const addMwRe = /(?:app|router)\\s*\\.\\s*add_middleware\\s*\\(\\s*([\\w.]+)/g;\n let m: RegExpExecArray | null;\n while ((m = addMwRe.exec(source)) !== null) {\n chain.push({ name: m[1], scope: 'middleware', file: file.path });\n }\n }\n\n // Leverage fastapi_depends edges for route-level dependency chain\n const dependsEdges = store.getEdgesByType('fastapi_depends');\n for (const edge of dependsEdges) {\n const ref = store.getNodeRef(edge.source_node_id);\n if (!ref) continue;\n let name = 'Depends';\n let filePath = '';\n if (ref.nodeType === 'symbol') {\n const sym = store.getSymbolById(ref.refId);\n if (sym) {\n name = sym.name;\n const f = store.getFileById(sym.file_id);\n filePath = f?.path ?? '';\n }\n }\n chain.push({ name, scope: 'depends', file: filePath });\n }\n}\n\n// ─── Django ───────────────────────────────────────────────────\n\nfunction buildDjangoChain(\n store: Store,\n rootPath: string,\n allFiles: FileInfo[],\n chain: MiddlewareEntry[],\n): void {\n // 1. settings.py MIDDLEWARE list\n for (const file of allFiles) {\n if (!file.path.endsWith('settings.py') && !file.path.includes('settings/')) continue;\n const source = readSource(rootPath, file.path);\n if (!source) continue;\n\n // MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', ... ]\n const mwMatch = source.match(/MIDDLEWARE\\s*=\\s*\\[([\\s\\S]*?)\\]/);\n if (!mwMatch) continue;\n\n const items = mwMatch[1].match(/['\"]([^'\"]+)['\"]/g);\n if (items) {\n for (const item of items) {\n const name = item.replace(/['\"]/g, '');\n chain.push({ name, scope: 'global', file: file.path });\n }\n }\n }\n\n // 2. View-level decorators (@login_required, @permission_required, etc.)\n for (const file of allFiles) {\n if (file.framework_role !== 'view') continue;\n const source = readSource(rootPath, file.path);\n if (!source) continue;\n\n const decoratorRe = /@([\\w.]+)\\s*(?:\\([^)]*\\))?\\s*\\n\\s*(?:@\\w[\\w.]*\\s*(?:\\([^)]*\\))?\\s*\\n\\s*)*(?:def|class)\\s+\\w+/g;\n let m: RegExpExecArray | null;\n while ((m = decoratorRe.exec(source)) !== null) {\n const dec = m[1];\n // Skip routing decorators\n if (dec.includes('route') || dec.includes('api_view')) continue;\n chain.push({ name: `@${dec}`, scope: 'view_decorator', file: file.path });\n }\n }\n}\n","/**\n * get_module_graph — NestJS module dependency graph.\n *\n * Traces: module -> imports -> controllers -> providers -> exports.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { Store } from '../db/store.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { notFound } from '../errors.js';\nimport { extractModuleInfo } from '../indexer/plugins/framework/nestjs/index.js';\n\nexport interface ModuleGraphNode {\n name: string;\n file?: string;\n imports: string[];\n controllers: string[];\n providers: string[];\n exports: string[];\n}\n\nexport interface ModuleGraphResult {\n rootModule: string;\n modules: ModuleGraphNode[];\n}\n\n/**\n * Build module dependency graph starting from a named NestJS module.\n */\nexport function getModuleGraph(\n store: Store,\n rootPath: string,\n moduleName: string,\n): TraceMcpResult<ModuleGraphResult> {\n const allFiles = store.getAllFiles();\n const moduleFiles = allFiles.filter((f) => f.framework_role === 'nest_module');\n\n if (moduleFiles.length === 0) {\n return err(notFound(moduleName, ['No NestJS modules found. Run reindex first.']));\n }\n\n // Build map of module name -> info\n const moduleMap = new Map<string, ModuleGraphNode>();\n\n for (const file of moduleFiles) {\n let source: string;\n try {\n source = fs.readFileSync(path.resolve(rootPath, file.path), 'utf-8');\n } catch { continue; }\n\n const info = extractModuleInfo(source);\n if (!info) continue;\n\n // Extract class name from file\n const classMatch = source.match(/export\\s+class\\s+(\\w+)/);\n const name = classMatch?.[1] ?? path.basename(file.path, path.extname(file.path));\n\n moduleMap.set(name, {\n name,\n file: file.path,\n imports: info.imports,\n controllers: info.controllers,\n providers: info.providers,\n exports: info.exports,\n });\n }\n\n // Find root module\n const rootModule = moduleMap.get(moduleName);\n if (!rootModule) {\n const available = [...moduleMap.keys()];\n return err(notFound(moduleName, available.length > 0\n ? [`Available modules: ${available.join(', ')}`]\n : ['No NestJS modules found']));\n }\n\n // BFS to collect reachable modules\n const visited = new Set<string>();\n const queue = [moduleName];\n const result: ModuleGraphNode[] = [];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n if (visited.has(current)) continue;\n visited.add(current);\n\n const mod = moduleMap.get(current);\n if (!mod) continue;\n\n result.push(mod);\n\n for (const imp of mod.imports) {\n if (!visited.has(imp)) {\n queue.push(imp);\n }\n }\n }\n\n return ok({ rootModule: moduleName, modules: result });\n}\n","/**\n * NestJSPlugin — detects NestJS projects and extracts modules, controllers,\n * routes, providers, and dependency injection edges.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport { escapeRegExp } from '../../../../utils/security.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\nconst HTTP_METHODS = ['Get', 'Post', 'Put', 'Delete', 'Patch', 'Head', 'Options'] as const;\nconst CONTROLLER_RE = /@Controller\\(\\s*['\"`]([^'\"`]*)['\"`]\\s*\\)/;\nconst METHOD_DECORATOR_RE = (method: string) =>\n new RegExp(`@${escapeRegExp(method)}\\\\(\\\\s*(?:['\"\\`]([^'\"\\`]*)['\"\\`])?\\\\s*\\\\)`, 'g');\nconst MODULE_RE = /@Module\\(\\s*\\{([^}]*(?:\\{[^}]*\\}[^}]*)*)\\}\\s*\\)/s;\nconst INJECTABLE_RE = /@Injectable\\(\\)/;\nconst USE_GUARDS_RE = /@UseGuards\\(\\s*([^)]+)\\s*\\)/g;\nconst USE_PIPES_RE = /@UsePipes\\(\\s*([^)]+)\\s*\\)/g;\nconst USE_INTERCEPTORS_RE = /@UseInterceptors\\(\\s*([^)]+)\\s*\\)/g;\nconst CONSTRUCTOR_RE = /constructor\\s*\\(([^)]*)\\)/s;\nconst GATEWAY_RE = /@WebSocketGateway\\s*\\(/;\nconst SUBSCRIBE_RE = /@SubscribeMessage\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*\\)/g;\nconst EVENT_PATTERN_RE = /@EventPattern\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*\\)/g;\nconst MICROSERVICE_RE = /@(MessagePattern|EventPattern)\\s*\\(/;\n\n/** Extract array items from a module decorator property like `imports: [A, B]`. */\nfunction extractModuleArray(body: string, prop: string): string[] {\n const re = new RegExp(`${escapeRegExp(prop)}\\\\s*:\\\\s*\\\\[([^\\\\]]*?)\\\\]`, 's');\n const m = body.match(re);\n if (!m) return [];\n return m[1]\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\n/** Extract constructor parameter types for DI. */\nexport function extractConstructorDeps(source: string): string[] {\n const m = source.match(CONSTRUCTOR_RE);\n if (!m) return [];\n const params = m[1];\n const deps: string[] = [];\n // Match patterns like: private userService: UserService\n const paramRe = /(?:private|protected|public|readonly)\\s+\\w+\\s*:\\s*(\\w+)/g;\n let match: RegExpExecArray | null;\n while ((match = paramRe.exec(params)) !== null) {\n deps.push(match[1]);\n }\n return deps;\n}\n\n/** Extract route info from a controller file. */\nexport function extractControllerRoutes(\n source: string,\n filePath: string,\n): { basePath: string; routes: RawRoute[]; guards: string[] } {\n const controllerMatch = source.match(CONTROLLER_RE);\n const basePath = controllerMatch ? controllerMatch[1] : '';\n const routes: RawRoute[] = [];\n const guards: string[] = [];\n\n // Extract class-level guards\n const classGuardMatch = source.match(USE_GUARDS_RE);\n if (classGuardMatch) {\n for (const gm of classGuardMatch) {\n const inner = gm.match(/@UseGuards\\(\\s*([^)]+)\\s*\\)/);\n if (inner) {\n guards.push(\n ...inner[1].split(',').map((s) => s.trim()).filter(Boolean),\n );\n }\n }\n }\n\n for (const method of HTTP_METHODS) {\n const re = METHOD_DECORATOR_RE(method);\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const methodPath = match[1] ?? '';\n const segments = [basePath, methodPath].filter(Boolean);\n const uri = '/' + segments.join('/').replace(/\\/+/g, '/').replace(/^\\//, '');\n routes.push({\n method: method.toUpperCase(),\n uri: uri || '/',\n });\n }\n }\n\n return { basePath, routes, guards };\n}\n\nexport function extractGatewayEvents(source: string): string[] {\n const events: string[] = [];\n const re = new RegExp(SUBSCRIBE_RE.source, 'g');\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n if (m[1]) events.push(m[1]);\n }\n return events;\n}\n\nexport function extractMicroservicePatterns(source: string): { type: 'message' | 'event'; pattern: string }[] {\n const results: { type: 'message' | 'event'; pattern: string }[] = [];\n const eventRe = new RegExp(EVENT_PATTERN_RE.source, 'g');\n let m: RegExpExecArray | null;\n while ((m = eventRe.exec(source)) !== null) {\n if (m[1]) results.push({ type: 'event', pattern: m[1] });\n }\n // @MessagePattern('cmd') or @MessagePattern({ cmd: 'sum' })\n const msgStr = /@MessagePattern\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*\\)/g;\n while ((m = msgStr.exec(source)) !== null) {\n if (m[1]) results.push({ type: 'message', pattern: m[1] });\n }\n const msgObj = /@MessagePattern\\s*\\(\\s*\\{[^}]*cmd\\s*:\\s*['\"`]([^'\"`]+)['\"`]/g;\n while ((m = msgObj.exec(source)) !== null) {\n if (m[1]) results.push({ type: 'message', pattern: m[1] });\n }\n return results;\n}\n\n/** Extract module metadata. */\nexport function extractModuleInfo(source: string): {\n imports: string[];\n controllers: string[];\n providers: string[];\n exports: string[];\n} | null {\n const m = source.match(MODULE_RE);\n if (!m) return null;\n const body = m[1];\n return {\n imports: extractModuleArray(body, 'imports'),\n controllers: extractModuleArray(body, 'controllers'),\n providers: extractModuleArray(body, 'providers'),\n exports: extractModuleArray(body, 'exports'),\n };\n}\n\nexport class NestJSPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'nestjs',\n version: '1.0.0',\n priority: 25,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if ('@nestjs/core' in deps) return true;\n }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n return '@nestjs/core' in deps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'nest_module_imports', category: 'nestjs', description: 'Module imports another module' },\n { name: 'nest_provides', category: 'nestjs', description: 'Module provides a service' },\n { name: 'nest_injects', category: 'nestjs', description: 'Constructor dependency injection' },\n { name: 'nest_guards', category: 'nestjs', description: 'UseGuards on controller/method' },\n { name: 'nest_pipes', category: 'nestjs', description: 'UsePipes on controller/method' },\n { name: 'nest_interceptors', category: 'nestjs', description: 'UseInterceptors on controller/method' },\n { name: 'nest_gateway_event', category: 'nestjs', description: 'WebSocket gateway @SubscribeMessage handler' },\n { name: 'nest_message_pattern', category: 'nestjs', description: 'Microservice @MessagePattern handler' },\n { name: 'nest_event_pattern', category: 'nestjs', description: 'Microservice @EventPattern handler' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'typescript') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = { status: 'ok', symbols: [], routes: [], edges: [] };\n\n // Controller with routes\n if (source.includes('@Controller')) {\n const { routes } = extractControllerRoutes(source, filePath);\n result.routes = routes;\n result.frameworkRole = 'nest_controller';\n }\n\n // Module\n if (source.includes('@Module')) {\n const moduleInfo = extractModuleInfo(source);\n if (moduleInfo) {\n result.frameworkRole = 'nest_module';\n }\n }\n\n // Injectable\n if (INJECTABLE_RE.test(source)) {\n result.frameworkRole = result.frameworkRole ?? 'nest_injectable';\n }\n\n // WebSocket Gateway\n if (GATEWAY_RE.test(source)) {\n result.frameworkRole = 'nest_gateway';\n const events = extractGatewayEvents(source);\n if (events.length > 0) {\n result.warnings = result.warnings ?? [];\n // store gateway events in metadata via a synthetic warning-free mechanism\n // Use routes as gateway event placeholders\n if (!result.routes) result.routes = [];\n for (const evt of events) {\n result.routes.push({ method: 'WS', uri: evt });\n }\n }\n }\n\n // Microservice handlers\n if (MICROSERVICE_RE.test(source)) {\n result.frameworkRole = result.frameworkRole ?? 'nest_microservice';\n const patterns = extractMicroservicePatterns(source);\n if (patterns.length > 0) {\n if (!result.routes) result.routes = [];\n for (const p of patterns) {\n result.routes.push({ method: p.type === 'message' ? 'MSG' : 'EVT', uri: p.pattern });\n }\n }\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n const allFiles = ctx.getAllFiles();\n\n // TypeScript symbols don't carry PHP-style FQNs, so build a class-name → symbol\n // map as a fallback for DI/module resolution.\n const classSymbolByName = new Map<string, { id: number }>();\n for (const file of allFiles) {\n if (file.language !== 'typescript') continue;\n for (const sym of ctx.getSymbolsByFile(file.id)) {\n if (sym.kind === 'class') {\n classSymbolByName.set(sym.name, { id: sym.id });\n }\n }\n }\n\n /** Try FQN first (PHP-style), fall back to plain class name (TypeScript). */\n const resolve = (name: string) =>\n ctx.getSymbolByFqn(name) ?? classSymbolByName.get(name);\n\n for (const file of allFiles) {\n if (file.language !== 'typescript') continue;\n\n const source = ctx.readFile(file.path);\n if (!source) continue;\n\n // Module edges\n const moduleInfo = extractModuleInfo(source);\n if (moduleInfo) {\n const symbols = ctx.getSymbolsByFile(file.id);\n const moduleClass = symbols.find((s) => s.kind === 'class');\n if (moduleClass) {\n // imports\n for (const imp of moduleInfo.imports) {\n const target = resolve(imp);\n if (target) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: moduleClass.id,\n targetNodeType: 'symbol',\n targetRefId: target.id,\n edgeType: 'nest_module_imports',\n });\n }\n }\n // providers\n for (const prov of moduleInfo.providers) {\n const target = resolve(prov);\n if (target) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: moduleClass.id,\n targetNodeType: 'symbol',\n targetRefId: target.id,\n edgeType: 'nest_provides',\n });\n }\n }\n }\n }\n\n // Constructor injection edges\n const deps = extractConstructorDeps(source);\n if (deps.length > 0) {\n const symbols = ctx.getSymbolsByFile(file.id);\n const cls = symbols.find((s) => s.kind === 'class');\n if (cls) {\n for (const dep of deps) {\n const target = resolve(dep);\n if (target) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: cls.id,\n targetNodeType: 'symbol',\n targetRefId: target.id,\n edgeType: 'nest_injects',\n metadata: { dependency: dep },\n });\n }\n }\n }\n }\n }\n\n return ok(edges);\n }\n}\n","/**\n * get_di_tree — NestJS dependency injection tree.\n *\n * Traces: service -> what it injects -> who injects it.\n */\nimport type { Store } from '../db/store.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { notFound } from '../errors.js';\n\nexport interface DINode {\n name: string;\n symbolId?: string;\n file?: string;\n}\n\nexport interface DITreeResult {\n service: DINode;\n injects: DINode[]; // what this service depends on\n injectedBy: DINode[]; // what depends on this service\n}\n\n/**\n * Build a DI tree for a NestJS service.\n * Uses nest_injects edges from the graph.\n */\nexport function getDITree(\n store: Store,\n serviceName: string,\n): TraceMcpResult<DITreeResult> {\n // Find the service symbol by name or FQN\n const symbol = store.getSymbolByFqn(serviceName)\n ?? findSymbolByName(store, serviceName);\n\n if (!symbol) {\n return err(notFound(serviceName, ['Service not found. Try using the full class name.']));\n }\n\n const file = store.getFileById(symbol.file_id);\n const service: DINode = {\n name: symbol.name,\n symbolId: symbol.symbol_id,\n file: file?.path,\n };\n\n const nodeId = store.getNodeId('symbol', symbol.id);\n if (nodeId == null) {\n return ok({ service, injects: [], injectedBy: [] });\n }\n\n // What this service injects (outgoing nest_injects edges)\n const outEdges = store.getOutgoingEdges(nodeId);\n const injects: DINode[] = [];\n\n for (const edge of outEdges) {\n if (edge.edge_type_name !== 'nest_injects') continue;\n const targetRef = store.getNodeByNodeId(edge.target_node_id);\n if (!targetRef || targetRef.node_type !== 'symbol') continue;\n\n const targetSym = store.getSymbolById(targetRef.ref_id);\n if (!targetSym) continue;\n\n const targetFile = store.getFileById(targetSym.file_id);\n injects.push({\n name: targetSym.name,\n symbolId: targetSym.symbol_id,\n file: targetFile?.path,\n });\n }\n\n // Who injects this service (incoming nest_injects edges)\n const inEdges = store.getIncomingEdges(nodeId);\n const injectedBy: DINode[] = [];\n\n for (const edge of inEdges) {\n if (edge.edge_type_name !== 'nest_injects') continue;\n const sourceRef = store.getNodeByNodeId(edge.source_node_id);\n if (!sourceRef || sourceRef.node_type !== 'symbol') continue;\n\n const sourceSym = store.getSymbolById(sourceRef.ref_id);\n if (!sourceSym) continue;\n\n const sourceFile = store.getFileById(sourceSym.file_id);\n injectedBy.push({\n name: sourceSym.name,\n symbolId: sourceSym.symbol_id,\n file: sourceFile?.path,\n });\n }\n\n return ok({ service, injects, injectedBy });\n}\n\nfunction findSymbolByName(\n store: Store,\n name: string,\n): ReturnType<Store['getSymbolByFqn']> {\n return store.getSymbolByName(name, 'class');\n}\n","/**\n * get_navigation_graph — React Native navigation tree.\n *\n * Builds full navigation tree from RN screens + navigators.\n */\nimport type { Store, RnScreenRow } from '../db/store.js';\nimport { ok, type TraceMcpResult } from '../errors.js';\n\nexport interface NavigationNode {\n screen: string;\n component?: string;\n navigatorType?: string;\n deepLink?: string;\n navigatesTo: string[];\n metadata?: Record<string, unknown>;\n}\n\nexport interface NavigationGraphResult {\n screens: NavigationNode[];\n navigatorTypes: string[];\n deepLinks: { screen: string; path: string }[];\n totalScreens: number;\n}\n\n/**\n * Build navigation graph from all indexed RN screens.\n */\nexport function getNavigationGraph(\n store: Store,\n): TraceMcpResult<NavigationGraphResult> {\n const allScreens = store.getAllRnScreens();\n\n // Build edges from edges table (rn_navigates_to)\n const navigatesMap = buildNavigatesMap(store, allScreens);\n\n const screens: NavigationNode[] = allScreens.map((s) => ({\n screen: s.name,\n component: s.component_path ?? undefined,\n navigatorType: s.navigator_type ?? undefined,\n deepLink: s.deep_link ?? undefined,\n navigatesTo: navigatesMap.get(s.name) ?? [],\n metadata: s.metadata ? JSON.parse(s.metadata) : undefined,\n }));\n\n const navigatorTypes = [\n ...new Set(allScreens.map((s) => s.navigator_type).filter(Boolean) as string[]),\n ];\n\n const deepLinks = allScreens\n .filter((s) => s.deep_link)\n .map((s) => ({ screen: s.name, path: s.deep_link! }));\n\n return ok({\n screens,\n navigatorTypes,\n deepLinks,\n totalScreens: allScreens.length,\n });\n}\n\n/**\n * Build a map of screen -> screens it navigates to,\n * using rn_navigates_to edges from the graph.\n */\nfunction buildNavigatesMap(\n store: Store,\n allScreens: RnScreenRow[],\n): Map<string, string[]> {\n const map = new Map<string, string[]>();\n\n // Pre-build nodeId → screenName lookup in one batch query (avoids O(edges*screens) N+1)\n const screenIds = allScreens.map((s) => s.id);\n const nodeIdMap = store.getNodeIdsBatch('rn_screen', screenIds);\n const nodeToScreen = new Map<number, string>();\n for (const screen of allScreens) {\n const nodeId = nodeIdMap.get(screen.id);\n if (nodeId !== undefined) nodeToScreen.set(nodeId, screen.name);\n }\n\n const navEdges = store.getEdgesByType('rn_navigates_to');\n for (const edge of navEdges) {\n const sourceName = nodeToScreen.get(edge.source_node_id);\n const targetName = nodeToScreen.get(edge.target_node_id);\n\n if (sourceName && targetName) {\n const existing = map.get(sourceName) ?? [];\n existing.push(targetName);\n map.set(sourceName, existing);\n }\n }\n\n return map;\n}\n","/**\n * get_screen_context tool — full context for a React Native screen.\n * Returns component info, navigator, navigation edges, deep link, platform variants.\n */\nimport type { Store, RnScreenRow } from '../db/store.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { notFound } from '../errors.js';\n\nexport interface ScreenContextResult {\n screen: string;\n component: string | undefined;\n filePath: string | undefined;\n navigatorType: string | undefined;\n navigatedFrom: string[];\n navigatesTo: string[];\n deepLink: string | undefined;\n platformSpecific: Record<string, string>;\n nativeModulesUsed: string[];\n params: Record<string, unknown> | undefined;\n}\n\nexport function getScreenContext(\n store: Store,\n screenName: string,\n): TraceMcpResult<ScreenContextResult> {\n let screen = store.getRnScreenByName(screenName);\n\n if (!screen) {\n // Try case-insensitive partial match\n const all = store.getAllRnScreens();\n screen = all.find((s) =>\n s.name.toLowerCase().includes(screenName.toLowerCase()),\n );\n }\n\n if (!screen) {\n return err(notFound(`screen:${screenName}`));\n }\n\n return ok(buildContext(store, screen));\n}\n\nfunction buildContext(store: Store, screen: RnScreenRow): ScreenContextResult {\n const metadata = screen.metadata ? JSON.parse(screen.metadata) : {};\n\n // Find screens that navigate TO this screen (incoming rn_navigates_to edges)\n const allScreens = store.getAllRnScreens();\n const navigatedFrom: string[] = [];\n const navigatesTo: string[] = [];\n\n for (const other of allScreens) {\n if (other.id === screen.id) continue;\n const otherMeta = other.metadata ? JSON.parse(other.metadata) : {};\n const calls: string[] = otherMeta.navigationCalls ?? [];\n if (calls.includes(screen.name)) {\n navigatedFrom.push(other.name);\n }\n }\n\n // Find screens this screen navigates to (from its metadata.navigationCalls)\n const myCalls: string[] = metadata.navigationCalls ?? [];\n for (const target of myCalls) {\n const found = allScreens.find(\n (s) => s.name === target || s.component_path?.includes(target),\n );\n if (found) navigatesTo.push(found.name);\n else navigatesTo.push(target);\n }\n\n // Platform-specific variants from metadata\n const platformSpecific: Record<string, string> = metadata.platformSpecific ?? {};\n\n // Native modules from metadata\n const nativeModulesUsed: string[] = metadata.nativeModules ?? [];\n\n // File path from file_id\n let filePath: string | undefined;\n const file = store.getFileById(screen.file_id);\n if (file) filePath = file.path;\n\n // Params from options JSON\n let params: Record<string, unknown> | undefined;\n if (screen.options) {\n try {\n const opts = JSON.parse(screen.options);\n if (opts.params) params = opts.params;\n } catch {\n // ignore\n }\n }\n\n return {\n screen: screen.name,\n component: screen.component_path ?? undefined,\n filePath,\n navigatorType: screen.navigator_type ?? undefined,\n navigatedFrom,\n navigatesTo,\n deepLink: screen.deep_link ?? undefined,\n platformSpecific,\n nativeModulesUsed,\n params,\n };\n}\n","/**\n * get_request_flow tool — traces a request from URL to full handler chain.\n * URL -> Route -> Middleware -> Controller -> FormRequest -> Model\n */\nimport type { Store, RouteRow } from '../db/store.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { notFound } from '../errors.js';\n\nexport interface RequestFlowStep {\n type: 'route' | 'middleware' | 'controller' | 'form_request' | 'model' | 'inertia_page';\n name: string;\n symbolId?: string;\n fqn?: string;\n details?: Record<string, unknown>;\n}\n\nexport interface RequestFlowResult {\n url: string;\n method: string;\n steps: RequestFlowStep[];\n _meta?: { warnings: string[] };\n}\n\nexport function getRequestFlow(\n store: Store,\n url: string,\n method: string,\n): TraceMcpResult<RequestFlowResult> {\n const normalizedMethod = method.toUpperCase();\n const steps: RequestFlowStep[] = [];\n const warnings: string[] = [];\n\n // 1. Find matching route\n const route = store.findRouteByPattern(url, normalizedMethod);\n if (!route) {\n return err(notFound(`route:${normalizedMethod} ${url}`));\n }\n\n steps.push({\n type: 'route',\n name: route.name ?? `${route.method} ${route.uri}`,\n details: {\n method: route.method,\n uri: route.uri,\n routeName: route.name,\n },\n });\n\n // 2. Parse middleware JSON and controller ref\n const { middleware, controllerRef } = parseRouteMiddleware(route);\n\n for (const m of middleware) {\n steps.push({ type: 'middleware', name: m });\n }\n\n // 3. Controller method\n const effectiveControllerRef = controllerRef ?? route.controller_symbol_id;\n if (effectiveControllerRef) {\n const ref = String(effectiveControllerRef);\n const [controllerFqn, actionName] = splitControllerRef(ref);\n\n const controllerSymbol = store.getSymbolByFqn(controllerFqn);\n const methodFqn = actionName ? `${controllerFqn}::${actionName}` : undefined;\n const methodSymbol = methodFqn ? store.getSymbolByFqn(methodFqn) : undefined;\n\n steps.push({\n type: 'controller',\n name: actionName ? `${controllerFqn}@${actionName}` : controllerFqn,\n symbolId: methodSymbol?.symbol_id ?? controllerSymbol?.symbol_id,\n fqn: methodFqn ?? controllerFqn,\n details: { action: actionName },\n });\n\n // 4. FormRequest — find validates_with edges from controller method\n // 5. Inertia — find inertia_renders edges from controller method OR class\n // Edges may be on the method or on the class symbol, so check both\n const symbolsToCheck = [methodSymbol, controllerSymbol].filter(Boolean) as typeof controllerSymbol[];\n const seenEdgeTypes = new Set<string>();\n\n for (const sym of symbolsToCheck) {\n if (!sym) continue;\n const nodeId = store.getNodeId('symbol', sym.id);\n if (!nodeId) continue;\n\n const outEdges = store.getOutgoingEdges(nodeId);\n for (const edge of outEdges) {\n if (edge.edge_type_name === 'validates_with' && !seenEdgeTypes.has('validates_with')) {\n const targetNode = store.getNodeByNodeId(edge.target_node_id);\n if (targetNode && targetNode.node_type === 'symbol') {\n const targetSym = store.getSymbolById(targetNode.ref_id);\n if (targetSym) {\n seenEdgeTypes.add('validates_with');\n steps.push({\n type: 'form_request',\n name: targetSym.fqn ?? targetSym.name,\n symbolId: targetSym.symbol_id,\n fqn: targetSym.fqn ?? undefined,\n });\n }\n }\n }\n\n if (edge.edge_type_name === 'inertia_renders') {\n const targetNode = store.getNodeByNodeId(edge.target_node_id);\n if (targetNode && targetNode.node_type === 'symbol') {\n const targetSym = store.getSymbolById(targetNode.ref_id);\n if (targetSym) {\n const meta = edge.metadata ? JSON.parse(edge.metadata) as Record<string, unknown> : {};\n const file = store.getFileById(targetSym.file_id);\n // Only include Inertia pages that are NOT already in steps\n const alreadyAdded = steps.some(\n (s) => s.type === 'inertia_page' && s.details?.pageName === meta.pageName,\n );\n if (!alreadyAdded) {\n steps.push({\n type: 'inertia_page',\n name: targetSym.name,\n symbolId: targetSym.symbol_id,\n details: {\n pageName: meta.pageName,\n propNames: meta.propNames,\n filePath: file?.path,\n },\n });\n }\n }\n }\n }\n }\n }\n }\n\n const result: RequestFlowResult = { url, method: normalizedMethod, steps };\n if (warnings.length > 0) {\n result._meta = { warnings };\n }\n return ok(result);\n}\n\n/** Parse the middleware JSON which may contain { middleware: [...], controllerRef: \"...\" }. */\nfunction parseRouteMiddleware(route: RouteRow): {\n middleware: string[];\n controllerRef: string | null;\n} {\n if (!route.middleware) return { middleware: [], controllerRef: null };\n\n try {\n const parsed = JSON.parse(route.middleware);\n if (Array.isArray(parsed)) {\n return { middleware: parsed, controllerRef: null };\n }\n if (typeof parsed === 'object' && parsed !== null) {\n return {\n middleware: Array.isArray(parsed.middleware) ? parsed.middleware : [],\n controllerRef: parsed.controllerRef ?? null,\n };\n }\n } catch {\n // not JSON\n }\n return { middleware: [], controllerRef: null };\n}\n\nfunction splitControllerRef(ref: string): [string, string | undefined] {\n // \"App\\Http\\Controllers\\UserController::store\"\n const lastSep = ref.lastIndexOf('::');\n if (lastSep > 0) {\n return [ref.substring(0, lastSep), ref.substring(lastSep + 2)];\n }\n return [ref, undefined];\n}\n","/**\n * get_model_context tool — assembles full context for an Eloquent, Mongoose, or Sequelize model.\n * Returns model symbol + relationships + schema + related controllers/requests.\n */\nimport type { Store, SymbolRow, OrmModelRow, OrmAssociationRow } from '../db/store.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { notFound } from '../errors.js';\n\nexport interface ModelRelationship {\n type: string; // edge type name: has_many, belongs_to, etc.\n relatedModel: string;\n relatedSymbolId?: string;\n method?: string;\n}\n\nexport interface ModelSchema {\n tableName: string;\n columns: Record<string, unknown>[];\n operation: string;\n timestamp?: string;\n}\n\nexport interface EcosystemRef {\n name: string;\n fqn?: string;\n symbolId?: string;\n}\n\nexport interface ModelContextResult {\n model: {\n name: string;\n fqn: string;\n symbolId: string;\n filePath: string;\n orm?: string;\n collection?: string;\n };\n relationships: ModelRelationship[];\n schema: ModelSchema[];\n relatedControllers: { name: string; symbolId: string; fqn: string | null }[];\n relatedRequests: { name: string; symbolId: string; fqn: string | null }[];\n ormMetadata?: Record<string, unknown>;\n /** Nova resource referencing this model */\n nova?: { resource: EcosystemRef; actions: string[]; filters: string[]; lenses: string[]; metrics: string[] };\n /** Filament resource referencing this model */\n filament?: { resource: EcosystemRef; relationManagers: string[]; pages: string[]; widgets: string[] };\n /** Livewire components using this model */\n livewireComponents?: EcosystemRef[];\n /** Data classes (DTOs) wrapping this model */\n dataClasses?: EcosystemRef[];\n}\n\nexport function getModelContext(\n store: Store,\n modelName: string,\n): TraceMcpResult<ModelContextResult> {\n // --- Try Mongoose / Sequelize ORM models first ---\n const ormModel = store.getOrmModelByName(modelName);\n if (ormModel) {\n return buildOrmModelContext(store, ormModel);\n }\n\n // --- Fall back to Eloquent (symbol-based) ---\n let modelSymbol: SymbolRow | undefined;\n\n modelSymbol = store.getSymbolByFqn(modelName);\n if (!modelSymbol) {\n modelSymbol = store.getSymbolByFqn(`App\\\\Models\\\\${modelName}`);\n }\n if (!modelSymbol) {\n const allSymbols = store.db.prepare(\n \"SELECT * FROM symbols WHERE name = ? AND kind = 'class'\",\n ).all(modelName) as SymbolRow[];\n modelSymbol = allSymbols[0];\n }\n\n if (!modelSymbol) {\n return err(notFound(`model:${modelName}`));\n }\n\n const file = store.getFileById(modelSymbol.file_id);\n if (!file) {\n return err(notFound(`file for model:${modelName}`));\n }\n\n const relationships = getRelationships(store, modelSymbol);\n const schema = getModelSchema(store, modelName);\n const relatedControllers = getRelatedByRole(store, modelSymbol, 'controller');\n const relatedRequests = getRelatedByRole(store, modelSymbol, 'form_request');\n\n // Ecosystem: find Nova/Filament/Livewire/Data referencing this model\n const eco = getEcosystemRefs(store, modelSymbol);\n\n return ok({\n model: {\n name: modelSymbol.name,\n fqn: modelSymbol.fqn ?? modelSymbol.name,\n symbolId: modelSymbol.symbol_id,\n filePath: file.path,\n },\n relationships,\n schema,\n relatedControllers,\n relatedRequests,\n ...eco,\n });\n}\n\nfunction buildOrmModelContext(\n store: Store,\n ormModel: OrmModelRow,\n): TraceMcpResult<ModelContextResult> {\n const file = store.getFileById(ormModel.file_id);\n const metadata: Record<string, unknown> = ormModel.metadata\n ? JSON.parse(ormModel.metadata)\n : {};\n\n // Associations from orm_associations table\n const assocRows: OrmAssociationRow[] = store.getOrmAssociationsByModel(ormModel.id);\n const relationships: ModelRelationship[] = assocRows.map((a) => ({\n type: a.kind,\n relatedModel: a.target_model_name ?? '',\n method: a.options ? (JSON.parse(a.options) as { as?: string }).as : undefined,\n }));\n\n // Schema from fields column (Mongoose/Sequelize)\n const fields: Record<string, unknown>[] = ormModel.fields\n ? JSON.parse(ormModel.fields)\n : [];\n\n const schema: ModelSchema[] = fields.length > 0\n ? [{\n tableName: ormModel.collection_or_table ?? ormModel.name.toLowerCase() + 's',\n columns: fields,\n operation: 'schema',\n }]\n : [];\n\n return ok({\n model: {\n name: ormModel.name,\n fqn: ormModel.name,\n symbolId: `orm:${ormModel.name}`,\n filePath: file?.path ?? '',\n orm: ormModel.orm,\n collection: ormModel.collection_or_table ?? undefined,\n },\n relationships,\n schema,\n relatedControllers: [],\n relatedRequests: [],\n ormMetadata: metadata,\n });\n}\n\nfunction getRelationships(store: Store, modelSymbol: SymbolRow): ModelRelationship[] {\n const relationships: ModelRelationship[] = [];\n const nodeId = store.getNodeId('symbol', modelSymbol.id);\n if (!nodeId) return relationships;\n\n const relEdgeTypes = ['has_many', 'belongs_to', 'belongs_to_many', 'has_one', 'morphs_to'];\n\n const outEdges = store.getOutgoingEdges(nodeId);\n for (const edge of outEdges) {\n if (!relEdgeTypes.includes(edge.edge_type_name)) continue;\n\n const targetNode = store.getNodeByNodeId(edge.target_node_id);\n if (!targetNode || targetNode.node_type !== 'symbol') continue;\n\n const targetSym = store.getSymbolById(targetNode.ref_id);\n if (!targetSym) continue;\n\n const metadata = edge.metadata ? JSON.parse(edge.metadata) : {};\n relationships.push({\n type: edge.edge_type_name,\n relatedModel: targetSym.fqn ?? targetSym.name,\n relatedSymbolId: targetSym.symbol_id,\n method: metadata.method,\n });\n }\n\n // Also check incoming edges (e.g. belongs_to from other models)\n const inEdges = store.getIncomingEdges(nodeId);\n for (const edge of inEdges) {\n if (!relEdgeTypes.includes(edge.edge_type_name)) continue;\n\n const sourceNode = store.getNodeByNodeId(edge.source_node_id);\n if (!sourceNode || sourceNode.node_type !== 'symbol') continue;\n\n const sourceSym = store.getSymbolById(sourceNode.ref_id);\n if (!sourceSym) continue;\n\n const metadata = edge.metadata ? JSON.parse(edge.metadata) : {};\n relationships.push({\n type: `inverse:${edge.edge_type_name}`,\n relatedModel: sourceSym.fqn ?? sourceSym.name,\n relatedSymbolId: sourceSym.symbol_id,\n method: metadata.method,\n });\n }\n\n return relationships;\n}\n\nfunction getModelSchema(store: Store, modelName: string): ModelSchema[] {\n // Guess table name from model name (e.g. User -> users, BlogPost -> blog_posts)\n const tableName = modelNameToTable(modelName);\n const migrations = store.getMigrationsByTable(tableName);\n\n return migrations.map((m) => ({\n tableName: m.table_name,\n columns: m.columns ? JSON.parse(m.columns) : [],\n operation: m.operation,\n timestamp: m.timestamp ?? undefined,\n }));\n}\n\nfunction getRelatedByRole(\n store: Store,\n _modelSymbol: SymbolRow,\n _role: string,\n): { name: string; symbolId: string; fqn: string | null }[] {\n // For now, return empty — this requires more complex graph traversal\n // that would need checking file framework_roles\n return [];\n}\n\n/**\n * Find Nova, Filament, Livewire, and laravel-data references to a model.\n * Searches incoming edges targeting the model's node.\n */\nfunction getEcosystemRefs(store: Store, modelSymbol: SymbolRow): Partial<ModelContextResult> {\n const nodeId = store.getNodeId('symbol', modelSymbol.id);\n if (!nodeId) return {};\n\n const incoming = store.getIncomingEdges(nodeId);\n const result: Partial<ModelContextResult> = {};\n\n // Nova\n for (const edge of incoming) {\n if (edge.edge_type_name !== 'nova_resource_for') continue;\n const src = resolveSourceSymbol(store, edge.source_node_id);\n if (!src) continue;\n const srcNodeId = store.getNodeId('symbol', src.id);\n const actions: string[] = [];\n const filters: string[] = [];\n const lenses: string[] = [];\n const metrics: string[] = [];\n if (srcNodeId) {\n for (const out of store.getOutgoingEdges(srcNodeId)) {\n const name = resolveTargetName(store, out.target_node_id, out.metadata);\n if (out.edge_type_name === 'nova_action_on' && name) actions.push(name);\n if (out.edge_type_name === 'nova_filter_on' && name) filters.push(name);\n if (out.edge_type_name === 'nova_lens_on' && name) lenses.push(name);\n if (out.edge_type_name === 'nova_metric_queries' && name) metrics.push(name);\n }\n }\n result.nova = {\n resource: { name: src.name, fqn: src.fqn ?? undefined, symbolId: src.symbol_id },\n actions, filters, lenses, metrics,\n };\n break;\n }\n\n // Filament\n for (const edge of incoming) {\n if (edge.edge_type_name !== 'filament_resource_for') continue;\n const src = resolveSourceSymbol(store, edge.source_node_id);\n if (!src) continue;\n const srcNodeId = store.getNodeId('symbol', src.id);\n const relationManagers: string[] = [];\n const pages: string[] = [];\n const widgets: string[] = [];\n if (srcNodeId) {\n for (const out of store.getOutgoingEdges(srcNodeId)) {\n const name = resolveTargetName(store, out.target_node_id, out.metadata);\n if (out.edge_type_name === 'filament_relation_manager' && name) relationManagers.push(name);\n if (out.edge_type_name === 'filament_page_for' && name) pages.push(name);\n if (out.edge_type_name === 'filament_widget_queries' && name) widgets.push(name);\n }\n }\n result.filament = {\n resource: { name: src.name, fqn: src.fqn ?? undefined, symbolId: src.symbol_id },\n relationManagers, pages, widgets,\n };\n break;\n }\n\n // Livewire components using this model\n const lwComponents: EcosystemRef[] = [];\n for (const edge of incoming) {\n if (edge.edge_type_name !== 'livewire_uses_model') continue;\n const src = resolveSourceSymbol(store, edge.source_node_id);\n if (src) lwComponents.push({ name: src.name, fqn: src.fqn ?? undefined, symbolId: src.symbol_id });\n }\n if (lwComponents.length > 0) result.livewireComponents = lwComponents;\n\n // Data classes wrapping this model\n const dataClasses: EcosystemRef[] = [];\n for (const edge of incoming) {\n if (edge.edge_type_name !== 'data_wraps') continue;\n const src = resolveSourceSymbol(store, edge.source_node_id);\n if (src) dataClasses.push({ name: src.name, fqn: src.fqn ?? undefined, symbolId: src.symbol_id });\n }\n if (dataClasses.length > 0) result.dataClasses = dataClasses;\n\n return result;\n}\n\nfunction resolveSourceSymbol(store: Store, sourceNodeId: number): SymbolRow | undefined {\n const sourceNode = store.getNodeByNodeId(sourceNodeId);\n if (!sourceNode || sourceNode.node_type !== 'symbol') return undefined;\n return store.getSymbolById(sourceNode.ref_id);\n}\n\nfunction resolveTargetName(store: Store, targetNodeId: number, metadataStr: string | null): string | undefined {\n const targetNode = store.getNodeByNodeId(targetNodeId);\n if (targetNode?.node_type === 'symbol') {\n const sym = store.getSymbolById(targetNode.ref_id);\n if (sym) return sym.fqn ?? sym.name;\n }\n if (metadataStr) {\n try {\n const meta = JSON.parse(metadataStr) as Record<string, unknown>;\n if (meta.targetFqn) return String(meta.targetFqn);\n } catch { /* ignore */ }\n }\n return undefined;\n}\n\n/** Convert a model class name to a table name (simple pluralization). */\nfunction modelNameToTable(name: string): string {\n // Strip namespace\n const short = name.includes('\\\\') ? name.split('\\\\').pop()! : name;\n // Simple snake_case + plural\n const snake = short.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();\n // Simple pluralization\n if (snake.endsWith('y') && !/[aeiou]y$/.test(snake)) return snake.slice(0, -1) + 'ies';\n if (/(?:s|sh|ch|x|z)$/.test(snake)) return snake + 'es';\n return snake + 's';\n}\n","/**\n * get_schema tool — reconstructs database schema from migrations.\n * Returns columns, types, and structure for a table or all tables.\n */\nimport type { Store } from '../db/store.js';\nimport { ok, type TraceMcpResult } from '../errors.js';\n\nexport interface TableColumn {\n name: string;\n type: string;\n nullable?: boolean;\n unique?: boolean;\n primary?: boolean;\n foreign?: boolean;\n default?: string;\n autoIncrement?: boolean;\n}\n\nexport interface TableSchema {\n tableName: string;\n columns: TableColumn[];\n operations: { operation: string; timestamp?: string }[];\n}\n\nexport interface SchemaResult {\n tables: TableSchema[];\n /** Mongoose/Sequelize ORM schemas (collections or model schemas) */\n ormSchemas?: OrmSchema[];\n}\n\nexport interface OrmSchema {\n name: string;\n orm: string;\n collection: string | undefined;\n fields: Record<string, unknown>[];\n indexes?: Record<string, unknown>[];\n}\n\nexport function getSchema(\n store: Store,\n tableName?: string,\n): TraceMcpResult<SchemaResult> {\n const tables: TableSchema[] = [];\n const ormSchemas: OrmSchema[] = [];\n\n if (tableName) {\n // Try SQL migrations first\n const schema = reconstructTable(store, tableName);\n if (schema) tables.push(schema);\n\n // Also try ORM model by name or collection\n const allOrm = store.getAllOrmModels();\n const ormMatch = allOrm.find(\n (m) =>\n m.name.toLowerCase() === tableName.toLowerCase() ||\n m.collection_or_table?.toLowerCase() === tableName.toLowerCase(),\n );\n if (ormMatch) {\n ormSchemas.push(buildOrmSchema(ormMatch));\n }\n } else {\n // All SQL tables\n const migrations = store.getAllMigrations();\n const tableNames = [...new Set(migrations.map((m) => m.table_name))];\n for (const name of tableNames) {\n const schema = reconstructTable(store, name);\n if (schema) tables.push(schema);\n }\n\n // All ORM models\n for (const m of store.getAllOrmModels()) {\n ormSchemas.push(buildOrmSchema(m));\n }\n }\n\n return ok({\n tables,\n ...(ormSchemas.length > 0 ? { ormSchemas } : {}),\n });\n}\n\nfunction buildOrmSchema(model: { name: string; orm: string; collection_or_table: string | null; fields: string | null; metadata: string | null }): OrmSchema {\n const fields: Record<string, unknown>[] = model.fields ? JSON.parse(model.fields) : [];\n const meta: Record<string, unknown> = model.metadata ? JSON.parse(model.metadata) : {};\n return {\n name: model.name,\n orm: model.orm,\n collection: model.collection_or_table ?? undefined,\n fields,\n ...(meta.indexes ? { indexes: meta.indexes as Record<string, unknown>[] } : {}),\n };\n}\n\nfunction reconstructTable(store: Store, tableName: string): TableSchema | null {\n const migrations = store.getMigrationsByTable(tableName);\n if (migrations.length === 0) return null;\n\n const columns: TableColumn[] = [];\n const operations: { operation: string; timestamp?: string }[] = [];\n const columnMap = new Map<string, TableColumn>();\n\n for (const mig of migrations) {\n operations.push({\n operation: mig.operation,\n timestamp: mig.timestamp ?? undefined,\n });\n\n if (mig.operation === 'drop') {\n // Table dropped — clear columns\n columnMap.clear();\n continue;\n }\n\n if (mig.columns) {\n const cols = JSON.parse(mig.columns) as Record<string, unknown>[];\n for (const col of cols) {\n const name = col.name as string;\n if (!name) continue;\n\n const tableCol: TableColumn = {\n name,\n type: (col.type as string) ?? 'unknown',\n };\n if (col.nullable) tableCol.nullable = true;\n if (col.unique) tableCol.unique = true;\n if (col.primary) tableCol.primary = true;\n if (col.foreign) tableCol.foreign = true;\n if (col.autoIncrement) tableCol.autoIncrement = true;\n if (col.default !== undefined) tableCol.default = String(col.default);\n\n columnMap.set(name, tableCol);\n }\n }\n }\n\n return {\n tableName,\n columns: [...columnMap.values()],\n operations,\n };\n}\n","/**\n * get_event_graph tool — shows event/listener relationships.\n * Finds events, their listeners, and dispatchers.\n */\nimport type { Store, SymbolRow } from '../db/store.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { notFound } from '../errors.js';\n\nexport interface BroadcastingInfo {\n channels: { name: string; type: string }[];\n broadcastAs?: string;\n payloadFields?: string[];\n}\n\nexport interface EventNode {\n name: string;\n fqn: string;\n symbolId: string;\n listeners: { name: string; fqn: string; symbolId: string }[];\n dispatchers: { name: string; fqn: string; symbolId: string }[];\n broadcasting?: BroadcastingInfo;\n}\n\nexport interface EventGraphResult {\n events: EventNode[];\n}\n\nexport function getEventGraph(\n store: Store,\n eventName?: string,\n): TraceMcpResult<EventGraphResult> {\n const events: EventNode[] = [];\n\n // Edge types that represent event-like relationships across frameworks\n const LISTENER_EDGE_TYPES = ['listens_to', 'django_signal_receiver'];\n const DISPATCH_EDGE_TYPES = ['dispatches', 'celery_dispatches'];\n\n if (eventName) {\n // Find specific event\n const eventSymbol = findEventSymbol(store, eventName);\n if (!eventSymbol) {\n return err(notFound(`event:${eventName}`));\n }\n const node = buildEventNode(store, eventSymbol, LISTENER_EDGE_TYPES, DISPATCH_EDGE_TYPES);\n events.push(node);\n } else {\n const seen = new Set<number>();\n\n // Find all events that have listener/dispatch edges targeting them\n for (const edgeType of [...LISTENER_EDGE_TYPES, ...DISPATCH_EDGE_TYPES]) {\n const edges = store.getEdgesByType(edgeType);\n for (const edge of edges) {\n if (seen.has(edge.target_node_id)) continue;\n seen.add(edge.target_node_id);\n\n const targetNode = store.getNodeByNodeId(edge.target_node_id);\n if (!targetNode || targetNode.node_type !== 'symbol') continue;\n\n const sym = store.getSymbolById(targetNode.ref_id);\n if (!sym) continue;\n\n events.push(buildEventNode(store, sym, LISTENER_EDGE_TYPES, DISPATCH_EDGE_TYPES));\n }\n }\n }\n\n return ok({ events });\n}\n\nfunction findEventSymbol(store: Store, name: string): SymbolRow | undefined {\n // Try FQN\n let sym = store.getSymbolByFqn(name);\n if (sym) return sym;\n\n // Try App\\Events\\ prefix\n sym = store.getSymbolByFqn(`App\\\\Events\\\\${name}`);\n if (sym) return sym;\n\n // Search by name\n const results = store.db.prepare(\n \"SELECT * FROM symbols WHERE name = ? AND kind = 'class'\",\n ).all(name) as SymbolRow[];\n return results[0];\n}\n\nfunction buildEventNode(\n store: Store,\n eventSymbol: SymbolRow,\n listenerEdgeTypes: string[],\n dispatchEdgeTypes: string[],\n): EventNode {\n const nodeId = store.getNodeId('symbol', eventSymbol.id);\n const listeners: { name: string; fqn: string; symbolId: string }[] = [];\n const dispatchers: { name: string; fqn: string; symbolId: string }[] = [];\n\n if (nodeId) {\n const inEdges = store.getIncomingEdges(nodeId);\n for (const edge of inEdges) {\n if (listenerEdgeTypes.includes(edge.edge_type_name)) {\n const sourceNode = store.getNodeByNodeId(edge.source_node_id);\n if (!sourceNode || sourceNode.node_type !== 'symbol') continue;\n const sym = store.getSymbolById(sourceNode.ref_id);\n if (sym) {\n listeners.push({ name: sym.name, fqn: sym.fqn ?? sym.name, symbolId: sym.symbol_id });\n }\n } else if (dispatchEdgeTypes.includes(edge.edge_type_name)) {\n const sourceNode = store.getNodeByNodeId(edge.source_node_id);\n if (!sourceNode || sourceNode.node_type !== 'symbol') continue;\n const sym = store.getSymbolById(sourceNode.ref_id);\n if (sym) {\n dispatchers.push({ name: sym.name, fqn: sym.fqn ?? sym.name, symbolId: sym.symbol_id });\n }\n }\n }\n }\n\n // Broadcasting: check for broadcasts_on and broadcast_as edges\n let broadcasting: BroadcastingInfo | undefined;\n if (nodeId) {\n const outEdges = store.getOutgoingEdges(nodeId);\n const channels: { name: string; type: string }[] = [];\n let broadcastAs: string | undefined;\n let payloadFields: string[] | undefined;\n\n for (const edge of outEdges) {\n const meta = edge.metadata ? JSON.parse(edge.metadata) as Record<string, unknown> : {};\n if (edge.edge_type_name === 'broadcasts_on') {\n channels.push({ name: String(meta.channelName ?? ''), type: String(meta.channelType ?? 'public') });\n } else if (edge.edge_type_name === 'broadcast_as') {\n broadcastAs = String(meta.broadcastAs ?? '');\n }\n }\n\n try {\n const symMeta = eventSymbol.metadata ? JSON.parse(eventSymbol.metadata) as Record<string, unknown> : {};\n if (Array.isArray(symMeta.payloadFields)) {\n payloadFields = symMeta.payloadFields as string[];\n }\n } catch { /* ignore */ }\n\n if (channels.length > 0) {\n broadcasting = { channels, broadcastAs, payloadFields };\n }\n }\n\n return {\n name: eventSymbol.name,\n fqn: eventSymbol.fqn ?? eventSymbol.name,\n symbolId: eventSymbol.symbol_id,\n listeners,\n dispatchers,\n broadcasting,\n };\n}\n","import type { Store, SymbolRow, FileRow } from '../db/store.js';\nimport { notFound, type TraceMcpResult } from '../errors.js';\nimport { ok, err } from 'neverthrow';\n\nexport interface ReferenceItem {\n /** Edge type describing the relationship (e.g. 'imports', 'calls', 'renders_component') */\n edge_type: string;\n /** Symbol that references the target (null if the referencing node is a file/route/component) */\n symbol: {\n symbol_id: string;\n name: string;\n kind: string;\n fqn: string | null;\n signature: string | null;\n line_start: number | null;\n } | null;\n file: string;\n}\n\nexport interface FindReferencesResult {\n target: {\n symbol_id?: string;\n file?: string;\n fqn?: string | null;\n };\n references: ReferenceItem[];\n total: number;\n}\n\n/**\n * Find all incoming references to a symbol or file node.\n * Returns every edge pointing at the target, with the referencing symbol resolved.\n */\nexport function findReferences(\n store: Store,\n opts: { symbolId?: string; fqn?: string; filePath?: string },\n): TraceMcpResult<FindReferencesResult> {\n let nodeId: number | undefined;\n let targetMeta: FindReferencesResult['target'] = {};\n\n if (opts.symbolId || opts.fqn) {\n let symbol: SymbolRow | undefined;\n if (opts.symbolId) {\n symbol = store.getSymbolBySymbolId(opts.symbolId);\n targetMeta.symbol_id = opts.symbolId;\n } else {\n symbol = store.getSymbolByFqn(opts.fqn!);\n targetMeta.fqn = opts.fqn;\n }\n if (!symbol) return err(notFound(opts.symbolId ?? opts.fqn ?? 'unknown'));\n const file = store.getFileById(symbol.file_id);\n if (file) targetMeta.file = file.path;\n nodeId = store.getNodeId('symbol', symbol.id);\n } else if (opts.filePath) {\n const file = store.getFile(opts.filePath);\n if (!file) return err(notFound(opts.filePath));\n targetMeta.file = file.path;\n nodeId = store.getNodeId('file', file.id);\n } else {\n return err(notFound('provide symbol_id, fqn, or file_path'));\n }\n\n if (nodeId === undefined) {\n // Node not in the graph (file indexed but no edges yet)\n return ok({ target: targetMeta, references: [], total: 0 });\n }\n\n const incomingEdges = store.getIncomingEdges(nodeId);\n const references: ReferenceItem[] = [];\n\n for (const edge of incomingEdges) {\n const sourceRef = store.getNodeRef(edge.source_node_id);\n if (!sourceRef) continue;\n\n let symbol: ReferenceItem['symbol'] = null;\n let filePath = '';\n\n if (sourceRef.nodeType === 'symbol') {\n const sym = store.getSymbolById(sourceRef.refId);\n if (!sym) continue;\n const f = store.getFileById(sym.file_id);\n filePath = f?.path ?? '';\n symbol = {\n symbol_id: sym.symbol_id,\n name: sym.name,\n kind: sym.kind,\n fqn: sym.fqn,\n signature: sym.signature,\n line_start: sym.line_start,\n };\n } else if (sourceRef.nodeType === 'file') {\n const f = store.getFileById(sourceRef.refId);\n filePath = f?.path ?? '';\n } else {\n // route / component / orm_model / rn_screen — just note the file via the ref table\n // We don't have a direct getById for all types, so skip detailed resolution\n filePath = `[${sourceRef.nodeType}:${sourceRef.refId}]`;\n }\n\n references.push({\n edge_type: edge.edge_type_name,\n symbol,\n file: filePath,\n });\n }\n\n return ok({ target: targetMeta, references, total: references.length });\n}\n","import type { Store } from '../db/store.js';\nimport { notFound, type TraceMcpResult } from '../errors.js';\nimport { ok, err } from 'neverthrow';\n\nexport interface CallGraphNode {\n symbol_id: string;\n name: string;\n kind: string;\n file: string;\n line: number | null;\n calls?: CallGraphNode[];\n called_by?: CallGraphNode[];\n}\n\nexport interface CallGraphResult {\n root: CallGraphNode;\n /** Edge types that were treated as calls */\n edge_types_used: string[];\n max_depth: number;\n}\n\nconst CALL_EDGE_TYPES = new Set([\n 'calls', 'references',\n // Framework-specific \"call\" semantics\n 'dispatches', 'routes_to', 'validates_with',\n 'nest_injects', 'graphql_resolves',\n]);\n\n/**\n * Build call graph centered on a symbol: who calls it (callers) and who it calls (callees).\n */\nconst MAX_DEPTH = 10;\n\nexport function getCallGraph(\n store: Store,\n opts: { symbolId?: string; fqn?: string },\n depth = 2,\n): TraceMcpResult<CallGraphResult> {\n depth = Math.min(depth, MAX_DEPTH);\n let symbol = opts.symbolId\n ? store.getSymbolBySymbolId(opts.symbolId)\n : opts.fqn ? store.getSymbolByFqn(opts.fqn) : undefined;\n\n if (!symbol) return err(notFound(opts.symbolId ?? opts.fqn ?? 'unknown'));\n\n const file = store.getFileById(symbol.file_id);\n const nodeId = store.getNodeId('symbol', symbol.id);\n if (!nodeId) {\n return ok({\n root: makeNode(symbol, file?.path ?? '', null, [], []),\n edge_types_used: [],\n max_depth: depth,\n });\n }\n\n const edgeTypesUsed = new Set<string>();\n const visited = new Set<number>();\n\n const rootNode = buildCallNode(store, symbol.id, nodeId, depth, visited, edgeTypesUsed);\n\n return ok({\n root: rootNode,\n edge_types_used: [...edgeTypesUsed],\n max_depth: depth,\n });\n}\n\nfunction buildCallNode(\n store: Store,\n symbolId: number,\n nodeId: number,\n depth: number,\n visited: Set<number>,\n edgeTypesUsed: Set<string>,\n): CallGraphNode {\n const symbol = store.getSymbolById(symbolId);\n const file = symbol ? store.getFileById(symbol.file_id) : undefined;\n\n if (!symbol) {\n return { symbol_id: '', name: '?', kind: 'unknown', file: '', line: null };\n }\n\n const node = makeNode(symbol, file?.path ?? '', symbol.line_start, [], []);\n visited.add(nodeId);\n\n if (depth <= 0) {\n delete node.calls;\n delete node.called_by;\n return node;\n }\n\n // Outgoing: what this symbol calls\n const outgoing = store.getOutgoingEdges(nodeId);\n for (const edge of outgoing) {\n if (!CALL_EDGE_TYPES.has(edge.edge_type_name)) continue;\n edgeTypesUsed.add(edge.edge_type_name);\n if (visited.has(edge.target_node_id)) continue;\n\n const ref = store.getNodeRef(edge.target_node_id);\n if (!ref || ref.nodeType !== 'symbol') continue;\n\n const child = buildCallNode(store, ref.refId, edge.target_node_id, depth - 1, new Set(visited), edgeTypesUsed);\n node.calls!.push(child);\n }\n\n // Incoming: who calls this symbol\n const incoming = store.getIncomingEdges(nodeId);\n for (const edge of incoming) {\n if (!CALL_EDGE_TYPES.has(edge.edge_type_name)) continue;\n edgeTypesUsed.add(edge.edge_type_name);\n if (visited.has(edge.source_node_id)) continue;\n\n const ref = store.getNodeRef(edge.source_node_id);\n if (!ref || ref.nodeType !== 'symbol') continue;\n\n const caller = buildCallNode(store, ref.refId, edge.source_node_id, depth - 1, new Set(visited), edgeTypesUsed);\n node.called_by!.push(caller);\n }\n\n // Prune empty arrays\n if (node.calls!.length === 0) delete node.calls;\n if (node.called_by!.length === 0) delete node.called_by;\n\n return node;\n}\n\nfunction makeNode(\n symbol: { symbol_id: string; name: string; kind: string },\n filePath: string,\n line: number | null,\n calls: CallGraphNode[],\n called_by: CallGraphNode[],\n): CallGraphNode {\n return { symbol_id: symbol.symbol_id, name: symbol.name, kind: symbol.kind, file: filePath, line, calls, called_by };\n}\n","import type { Store } from '../db/store.js';\nimport { notFound, type TraceMcpResult } from '../errors.js';\nimport { ok, err } from 'neverthrow';\n\nexport interface LivewireProperty {\n name: string;\n type?: string;\n is_lazy?: boolean;\n}\n\nexport interface LivewireAction {\n name: string;\n wire_targets?: string[]; // wire:click=\"methodName\" found in blade\n}\n\nexport interface LivewireContextResult {\n component_class: {\n symbol_id: string;\n name: string;\n file: string;\n };\n view?: {\n path: string;\n symbol_id?: string;\n };\n properties: LivewireProperty[];\n actions: LivewireAction[];\n events: {\n dispatches: string[];\n listens: string[];\n };\n child_components: string[];\n uses_model?: string;\n version?: 'v2' | 'v3';\n}\n\n/**\n * Get full context for a Livewire component: properties, actions,\n * events (dispatched/listened), associated view, and child components.\n */\nexport function getLivewireContext(\n store: Store,\n componentName: string,\n): TraceMcpResult<LivewireContextResult> {\n // Find the symbol for the Livewire component class\n const symbol = store.getSymbolByFqn(componentName)\n ?? findLivewireSymbol(store, componentName);\n\n if (!symbol) return err(notFound(componentName));\n\n const file = store.getFileById(symbol.file_id);\n if (!file) return err(notFound(`file for ${componentName}`));\n\n const nodeId = store.getNodeId('symbol', symbol.id);\n\n // Parse metadata stored by the Livewire indexer plugin\n let meta: Record<string, unknown> = {};\n try {\n if (symbol.metadata) meta = JSON.parse(symbol.metadata) as Record<string, unknown>;\n } catch { /* ignore */ }\n\n const properties: LivewireProperty[] = [];\n const actions: LivewireAction[] = [];\n\n // Extract properties from metadata\n if (Array.isArray(meta.properties)) {\n for (const p of meta.properties as Record<string, unknown>[]) {\n properties.push({ name: String(p.name ?? ''), type: p.type as string | undefined });\n }\n }\n\n // Extract actions/methods from metadata\n if (Array.isArray(meta.actions)) {\n for (const a of meta.actions as Record<string, unknown>[]) {\n actions.push({ name: String(a.name ?? '') });\n }\n }\n\n // Resolve edges for events, view, child components\n const dispatches: string[] = [];\n const listens: string[] = [];\n const childComponents: string[] = [];\n let viewPath: string | undefined;\n let viewSymbolId: string | undefined;\n let usesModel: string | undefined;\n\n if (nodeId !== undefined) {\n const outgoing = store.getOutgoingEdges(nodeId);\n for (const edge of outgoing) {\n switch (edge.edge_type_name) {\n case 'livewire_renders': {\n const ref = store.getNodeRef(edge.target_node_id);\n if (ref) {\n const target = ref.nodeType === 'file'\n ? store.getFileById(ref.refId)\n : store.getSymbolById(ref.refId);\n if (target && 'path' in target) viewPath = target.path;\n else if (target && 'symbol_id' in target) {\n viewSymbolId = target.symbol_id;\n const f = store.getFileById(target.file_id);\n if (f) viewPath = f.path;\n }\n }\n break;\n }\n case 'livewire_dispatches': {\n const edgeMeta = edge.metadata ? JSON.parse(edge.metadata) as Record<string, unknown> : {};\n if (edgeMeta.event) dispatches.push(String(edgeMeta.event));\n break;\n }\n case 'livewire_uses_model': {\n const ref = store.getNodeRef(edge.target_node_id);\n if (ref?.nodeType === 'symbol') {\n const s = store.getSymbolById(ref.refId);\n if (s) usesModel = s.name;\n }\n break;\n }\n case 'livewire_child_of':\n case 'livewire_form': {\n const ref = store.getNodeRef(edge.target_node_id);\n if (ref?.nodeType === 'symbol') {\n const s = store.getSymbolById(ref.refId);\n if (s) childComponents.push(s.name);\n }\n break;\n }\n }\n }\n\n const incoming = store.getIncomingEdges(nodeId);\n for (const edge of incoming) {\n if (edge.edge_type_name === 'livewire_listens') {\n const edgeMeta = edge.metadata ? JSON.parse(edge.metadata) as Record<string, unknown> : {};\n if (edgeMeta.event) listens.push(String(edgeMeta.event));\n }\n }\n }\n\n const version = (meta.version as 'v2' | 'v3' | undefined) ?? detectVersion(meta);\n\n return ok({\n component_class: {\n symbol_id: symbol.symbol_id,\n name: symbol.name,\n file: file.path,\n },\n view: viewPath ? { path: viewPath, symbol_id: viewSymbolId } : undefined,\n properties,\n actions,\n events: { dispatches, listens },\n child_components: childComponents,\n uses_model: usesModel,\n version,\n });\n}\n\nfunction findLivewireSymbol(store: Store, name: string) {\n return store.findSymbolByRole(name, 'livewire_component');\n}\n\nfunction detectVersion(meta: Record<string, unknown>): 'v2' | 'v3' | undefined {\n if (meta.isV3 === true || meta.useForms === true) return 'v3';\n if (meta.isV2 === true) return 'v2';\n return undefined;\n}\n","/**\n * get_nova_resource — assembles full context for a Laravel Nova resource.\n * Returns: model mapping, relationship fields, actions, filters, lenses, metrics.\n */\nimport type { Store } from '../db/store.js';\nimport { ok, err, type TraceMcpResult } from '../errors.js';\nimport { notFound } from '../errors.js';\n\nexport interface NovaFieldInfo {\n fieldType: string;\n label: string;\n attribute: string;\n targetResource?: string;\n}\n\nexport interface NovaResourceResult {\n resource: {\n name: string;\n fqn: string;\n symbolId: string;\n filePath: string;\n };\n model?: {\n name: string;\n fqn: string;\n symbolId?: string;\n };\n fields: NovaFieldInfo[];\n actions: string[];\n filters: string[];\n lenses: string[];\n metrics: string[];\n}\n\nexport function getNovaResource(\n store: Store,\n resourceName: string,\n): TraceMcpResult<NovaResourceResult> {\n // Find the Nova resource symbol\n const symbol = store.getSymbolByFqn(resourceName)\n ?? store.getSymbolByFqn(`App\\\\Nova\\\\${resourceName}`)\n ?? findNovaSymbol(store, resourceName);\n\n if (!symbol) return err(notFound(`nova_resource:${resourceName}`));\n\n const file = store.getFileById(symbol.file_id);\n if (!file) return err(notFound(`file for nova_resource:${resourceName}`));\n\n const nodeId = store.getNodeId('symbol', symbol.id);\n\n // Collect edges\n let modelInfo: NovaResourceResult['model'];\n const fields: NovaFieldInfo[] = [];\n const actions: string[] = [];\n const filters: string[] = [];\n const lenses: string[] = [];\n const metrics: string[] = [];\n\n if (nodeId !== undefined) {\n const outgoing = store.getOutgoingEdges(nodeId);\n for (const edge of outgoing) {\n const meta = edge.metadata ? JSON.parse(edge.metadata) as Record<string, unknown> : {};\n\n switch (edge.edge_type_name) {\n case 'nova_resource_for': {\n const targetNode = store.getNodeByNodeId(edge.target_node_id);\n if (targetNode?.node_type === 'symbol') {\n const targetSym = store.getSymbolById(targetNode.ref_id);\n if (targetSym) {\n modelInfo = {\n name: targetSym.name,\n fqn: targetSym.fqn ?? targetSym.name,\n symbolId: targetSym.symbol_id,\n };\n }\n }\n if (!modelInfo && meta.targetFqn) {\n modelInfo = { name: String(meta.targetFqn).split('\\\\').pop()!, fqn: String(meta.targetFqn) };\n }\n break;\n }\n case 'nova_field_relationship': {\n fields.push({\n fieldType: String(meta.fieldType ?? ''),\n label: String(meta.label ?? ''),\n attribute: String(meta.attribute ?? ''),\n targetResource: meta.targetFqn as string | undefined,\n });\n break;\n }\n case 'nova_action_on': {\n const name = resolveTargetName(store, edge.target_node_id, meta);\n if (name) actions.push(name);\n break;\n }\n case 'nova_filter_on': {\n const name = resolveTargetName(store, edge.target_node_id, meta);\n if (name) filters.push(name);\n break;\n }\n case 'nova_lens_on': {\n const name = resolveTargetName(store, edge.target_node_id, meta);\n if (name) lenses.push(name);\n break;\n }\n case 'nova_metric_queries': {\n const name = resolveTargetName(store, edge.target_node_id, meta);\n if (name) metrics.push(name);\n break;\n }\n }\n }\n }\n\n // Also try to extract from metadata if edges weren't resolved\n if (fields.length === 0 || actions.length === 0) {\n try {\n const meta = symbol.metadata ? JSON.parse(symbol.metadata) as Record<string, unknown> : {};\n if (Array.isArray(meta.fieldRelationships) && fields.length === 0) {\n for (const f of meta.fieldRelationships as Record<string, unknown>[]) {\n fields.push({\n fieldType: String(f.fieldType ?? ''),\n label: String(f.label ?? ''),\n attribute: String(f.attribute ?? ''),\n targetResource: f.targetResourceFqn as string | undefined,\n });\n }\n }\n if (Array.isArray(meta.actions) && actions.length === 0) {\n for (const a of meta.actions as string[]) actions.push(a);\n }\n if (Array.isArray(meta.filters) && filters.length === 0) {\n for (const f of meta.filters as string[]) filters.push(f);\n }\n if (Array.isArray(meta.lenses) && lenses.length === 0) {\n for (const l of meta.lenses as string[]) lenses.push(l);\n }\n if (Array.isArray(meta.metrics) && metrics.length === 0) {\n for (const m of meta.metrics as string[]) metrics.push(m);\n }\n if (!modelInfo && meta.modelFqn) {\n const fqn = String(meta.modelFqn);\n modelInfo = { name: fqn.split('\\\\').pop()!, fqn };\n }\n } catch { /* ignore */ }\n }\n\n return ok({\n resource: {\n name: symbol.name,\n fqn: symbol.fqn ?? symbol.name,\n symbolId: symbol.symbol_id,\n filePath: file.path,\n },\n model: modelInfo,\n fields,\n actions,\n filters,\n lenses,\n metrics,\n });\n}\n\nfunction findNovaSymbol(store: Store, name: string) {\n return store.findSymbolByRole(name, 'nova_resource');\n}\n\nfunction resolveTargetName(\n store: Store,\n targetNodeId: number,\n meta: Record<string, unknown>,\n): string | undefined {\n const targetNode = store.getNodeByNodeId(targetNodeId);\n if (targetNode?.node_type === 'symbol') {\n const sym = store.getSymbolById(targetNode.ref_id);\n if (sym) return sym.fqn ?? sym.name;\n }\n if (meta.targetFqn) return String(meta.targetFqn);\n return undefined;\n}\n","import path from 'node:path';\nimport type { Store } from '../db/store.js';\nimport { notFound, type TraceMcpResult } from '../errors.js';\nimport { ok, err } from 'neverthrow';\n\nexport interface TestReference {\n test_file: string;\n /** Symbol ID of the test function/method, if resolved */\n symbol_id?: string;\n test_name?: string;\n edge_type: string;\n}\n\nexport interface GetTestsForResult {\n target: { symbol_id?: string; file?: string };\n tests: TestReference[];\n total: number;\n}\n\n/**\n * Find test files/symbols that cover a given symbol or file.\n *\n * Strategy (in order):\n * 1. Walk incoming `test_covers` edges (explicit — for future use when\n * test frameworks emit these edges).\n * 2. Heuristic path-based matching: look for test files whose path contains\n * the target file's base name (e.g. UserService → user.service.spec.ts).\n * 3. FTS search for the symbol name inside files whose path matches\n * common test patterns.\n */\nexport function getTestsFor(\n store: Store,\n opts: { symbolId?: string; fqn?: string; filePath?: string },\n): TraceMcpResult<GetTestsForResult> {\n let targetFile: string | undefined;\n let targetSymbolId: string | undefined;\n let nodeId: number | undefined;\n\n if (opts.symbolId || opts.fqn) {\n const symbol = opts.symbolId\n ? store.getSymbolBySymbolId(opts.symbolId)\n : store.getSymbolByFqn(opts.fqn!);\n if (!symbol) return err(notFound(opts.symbolId ?? opts.fqn ?? 'unknown'));\n targetSymbolId = symbol.symbol_id;\n const f = store.getFileById(symbol.file_id);\n if (f) targetFile = f.path;\n nodeId = store.getNodeId('symbol', symbol.id);\n } else if (opts.filePath) {\n const f = store.getFile(opts.filePath);\n if (!f) return err(notFound(opts.filePath));\n targetFile = f.path;\n nodeId = store.getNodeId('file', f.id);\n } else {\n return err(notFound('provide symbol_id, fqn, or file_path'));\n }\n\n const tests: TestReference[] = [];\n const seen = new Set<string>();\n\n // Strategy 1: explicit test_covers edges\n if (nodeId !== undefined) {\n const incoming = store.getIncomingEdges(nodeId);\n for (const edge of incoming) {\n if (edge.edge_type_name !== 'test_covers') continue;\n const ref = store.getNodeRef(edge.source_node_id);\n if (!ref) continue;\n\n if (ref.nodeType === 'file') {\n const f = store.getFileById(ref.refId);\n if (!f || seen.has(f.path)) continue;\n seen.add(f.path);\n tests.push({ test_file: f.path, edge_type: 'test_covers' });\n } else if (ref.nodeType === 'symbol') {\n const s = store.getSymbolById(ref.refId);\n const f = s ? store.getFileById(s.file_id) : undefined;\n if (!s || !f || seen.has(f.path)) continue;\n seen.add(f.path);\n tests.push({\n test_file: f.path,\n symbol_id: s.symbol_id,\n test_name: s.name,\n edge_type: 'test_covers',\n });\n }\n }\n }\n\n // Strategy 2: heuristic path-based matching\n if (targetFile) {\n const baseName = path.basename(targetFile, path.extname(targetFile));\n // Normalize: UserService → user-service, userService → user-service\n const normalized = baseName\n .replace(/([A-Z])/g, (m) => `-${m.toLowerCase()}`)\n .replace(/^-/, '')\n .toLowerCase();\n const variants = [baseName.toLowerCase(), normalized];\n\n const allFiles = store.getAllFiles();\n for (const f of allFiles) {\n if (seen.has(f.path)) continue;\n if (!isTestFile(f.path)) continue;\n\n const testBase = path.basename(f.path).toLowerCase();\n if (variants.some((v) => testBase.includes(v))) {\n seen.add(f.path);\n tests.push({ test_file: f.path, edge_type: 'heuristic_path' });\n }\n }\n }\n\n return ok({\n target: { symbol_id: targetSymbolId, file: targetFile },\n tests,\n total: tests.length,\n });\n}\n\nconst TEST_PATTERNS = [\n /\\.test\\.[jt]sx?$/,\n /\\.spec\\.[jt]sx?$/,\n /_test\\.py$/,\n /test_\\w+\\.py$/,\n /Test\\.php$/,\n /tests?\\//,\n /__tests__\\//,\n];\n\nfunction isTestFile(filePath: string): boolean {\n return TEST_PATTERNS.some((re) => re.test(filePath));\n}\n","/**\n * Introspection tools — primarily useful for developing trace-mcp itself.\n *\n * Tools:\n * get_implementations — find all TypeScript classes/interfaces that\n * extend or implement a given name.\n * get_api_surface — list all exported symbols grouped by file.\n * get_plugin_registry — list registered plugins, their manifests,\n * and all known edge types.\n */\nimport type { Store, SymbolWithFilePath, SymbolRow } from '../db/store.js';\nimport type { PluginRegistry } from '../plugin-api/registry.js';\n\n/** Safely parse JSON metadata — returns empty object on malformed input. */\nfunction safeParseMeta(raw: string | null | undefined): Record<string, unknown> {\n if (!raw) return {};\n try { return JSON.parse(raw) as Record<string, unknown>; } catch { return {}; }\n}\n\n// ---------------------------------------------------------------------------\n// get_implementations\n// ---------------------------------------------------------------------------\n\nexport interface ImplementorItem {\n symbol_id: string;\n name: string;\n kind: string;\n signature: string | null;\n file: string;\n line: number | null;\n relation: 'implements' | 'extends';\n /** raw metadata.implements / metadata.extends value */\n via: string | string[];\n}\n\nexport interface GetImplementationsResult {\n target: string;\n implementors: ImplementorItem[];\n total: number;\n}\n\nexport function getImplementations(\n store: Store,\n name: string,\n): GetImplementationsResult {\n const rows = store.findImplementors(name);\n\n const implementors: ImplementorItem[] = rows.map((row) => {\n const meta = safeParseMeta(row.metadata);\n const imp = meta['implements'];\n const ext = meta['extends'];\n\n // Determine whether this is an implements or extends relation\n let relation: 'implements' | 'extends' = 'extends';\n let via: string | string[] = ext as string | string[];\n if (Array.isArray(imp) && imp.includes(name)) {\n relation = 'implements';\n via = imp;\n }\n\n return {\n symbol_id: row.symbol_id,\n name: row.name,\n kind: row.kind,\n signature: row.signature,\n file: row.file_path,\n line: row.line_start,\n relation,\n via,\n };\n });\n\n return { target: name, implementors, total: implementors.length };\n}\n\n// ---------------------------------------------------------------------------\n// get_api_surface\n// ---------------------------------------------------------------------------\n\nexport interface ApiSurfaceSymbol {\n symbol_id: string;\n name: string;\n kind: string;\n signature: string | null;\n line: number | null;\n default: boolean;\n}\n\nexport interface ApiSurfaceFile {\n file: string;\n exports: ApiSurfaceSymbol[];\n}\n\nexport interface GetApiSurfaceResult {\n file_pattern: string | null;\n files: ApiSurfaceFile[];\n total_symbols: number;\n}\n\nexport function getApiSurface(\n store: Store,\n filePattern?: string,\n): GetApiSurfaceResult {\n const rows = store.getExportedSymbols(filePattern);\n\n // Group by file\n const byFile = new Map<string, ApiSurfaceSymbol[]>();\n for (const row of rows) {\n const meta = safeParseMeta(row.metadata);\n const sym: ApiSurfaceSymbol = {\n symbol_id: row.symbol_id,\n name: row.name,\n kind: row.kind,\n signature: row.signature,\n line: row.line_start,\n default: Boolean(meta['default']),\n };\n const list = byFile.get(row.file_path) ?? [];\n list.push(sym);\n byFile.set(row.file_path, list);\n }\n\n const files: ApiSurfaceFile[] = [];\n for (const [file, exports] of byFile) {\n files.push({ file, exports });\n }\n\n return {\n file_pattern: filePattern ?? null,\n files,\n total_symbols: rows.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// get_plugin_registry\n// ---------------------------------------------------------------------------\n\nexport interface LanguagePluginInfo {\n name: string;\n version: string;\n priority: number;\n extensions: string[];\n}\n\nexport interface FrameworkPluginInfo {\n name: string;\n version: string;\n priority: number;\n dependencies: string[];\n active: boolean;\n}\n\nexport interface EdgeTypeInfo {\n name: string;\n category: string;\n description: string;\n}\n\nexport interface GetPluginRegistryResult {\n language_plugins: LanguagePluginInfo[];\n framework_plugins: FrameworkPluginInfo[];\n edge_types: EdgeTypeInfo[];\n active_frameworks: string[];\n}\n\nexport function getPluginRegistry(\n store: Store,\n registry: PluginRegistry,\n activeFrameworkNames: Set<string>,\n): GetPluginRegistryResult {\n const languagePlugins: LanguagePluginInfo[] = registry\n .getLanguagePlugins()\n .map((p) => ({\n name: p.manifest.name,\n version: p.manifest.version,\n priority: p.manifest.priority,\n extensions: p.supportedExtensions,\n }));\n\n const frameworkPlugins: FrameworkPluginInfo[] = registry\n .getAllFrameworkPlugins()\n .map((p) => ({\n name: p.manifest.name,\n version: p.manifest.version,\n priority: p.manifest.priority,\n dependencies: p.manifest.dependencies ?? [],\n active: activeFrameworkNames.has(p.manifest.name),\n }));\n\n const edgeTypes = store.getEdgeTypes();\n\n return {\n language_plugins: languagePlugins,\n framework_plugins: frameworkPlugins,\n edge_types: edgeTypes,\n active_frameworks: [...activeFrameworkNames].sort(),\n };\n}\n\n// ---------------------------------------------------------------------------\n// get_type_hierarchy\n// ---------------------------------------------------------------------------\n\nexport interface HierarchyNode {\n name: string;\n kind: string;\n symbol_id: string;\n file: string;\n line: number | null;\n relation: 'root' | 'extends' | 'implements';\n children: HierarchyNode[];\n}\n\nexport interface GetTypeHierarchyResult {\n root: string;\n ancestors: HierarchyNode[];\n descendants: HierarchyNode[];\n}\n\n/**\n * Walk TypeScript class/interface hierarchy up (ancestors) and down (descendants).\n * Uses metadata.extends / metadata.implements stored by the TypeScript plugin.\n */\nexport function getTypeHierarchy(\n store: Store,\n name: string,\n maxDepth = 10,\n): GetTypeHierarchyResult {\n // Walk UP: follow extends chain\n const ancestors: HierarchyNode[] = [];\n walkAncestors(store, name, ancestors, new Set(), maxDepth);\n\n // Walk DOWN: find implementors/subclasses recursively\n const descendants: HierarchyNode[] = [];\n walkDescendants(store, name, descendants, new Set(), maxDepth);\n\n return { root: name, ancestors, descendants };\n}\n\nfunction walkAncestors(\n store: Store,\n name: string,\n result: HierarchyNode[],\n visited: Set<string>,\n depth: number,\n): void {\n if (depth <= 0 || visited.has(name)) return;\n visited.add(name);\n\n // Find the symbol by name\n const sym = store.getSymbolByName(name, 'class') ?? store.getSymbolByName(name, 'interface');\n if (!sym) return;\n\n const meta = sym.metadata ? (JSON.parse(sym.metadata) as Record<string, unknown>) : {};\n const ext = meta['extends'];\n const extNames = Array.isArray(ext) ? ext as string[] : typeof ext === 'string' ? [ext] : [];\n const implNames = Array.isArray(meta['implements']) ? meta['implements'] as string[] : [];\n\n const file = store.getFileById(sym.file_id);\n\n for (const parentName of extNames) {\n const node: HierarchyNode = {\n name: parentName,\n kind: 'unknown',\n symbol_id: '',\n file: '',\n line: null,\n relation: 'extends',\n children: [],\n };\n // Try to resolve the parent\n const parentSym = store.getSymbolByName(parentName, 'class') ?? store.getSymbolByName(parentName, 'interface');\n if (parentSym) {\n const parentFile = store.getFileById(parentSym.file_id);\n node.kind = parentSym.kind;\n node.symbol_id = parentSym.symbol_id;\n node.file = parentFile?.path ?? '';\n node.line = parentSym.line_start;\n }\n result.push(node);\n walkAncestors(store, parentName, node.children, visited, depth - 1);\n }\n\n for (const ifaceName of implNames) {\n const node: HierarchyNode = {\n name: ifaceName,\n kind: 'interface',\n symbol_id: '',\n file: '',\n line: null,\n relation: 'implements',\n children: [],\n };\n const ifaceSym = store.getSymbolByName(ifaceName, 'interface');\n if (ifaceSym) {\n const ifaceFile = store.getFileById(ifaceSym.file_id);\n node.symbol_id = ifaceSym.symbol_id;\n node.file = ifaceFile?.path ?? '';\n node.line = ifaceSym.line_start;\n }\n result.push(node);\n walkAncestors(store, ifaceName, node.children, visited, depth - 1);\n }\n}\n\nfunction walkDescendants(\n store: Store,\n name: string,\n result: HierarchyNode[],\n visited: Set<string>,\n depth: number,\n): void {\n if (depth <= 0 || visited.has(name)) return;\n visited.add(name);\n\n const implementors = store.findImplementors(name);\n\n for (const row of implementors) {\n const meta = safeParseMeta(row.metadata);\n const impl = meta['implements'];\n const ext = meta['extends'];\n\n let relation: 'extends' | 'implements' = 'extends';\n if (Array.isArray(impl) && (impl as string[]).includes(name)) {\n relation = 'implements';\n }\n\n const node: HierarchyNode = {\n name: row.name,\n kind: row.kind,\n symbol_id: row.symbol_id,\n file: row.file_path,\n line: row.line_start,\n relation,\n children: [],\n };\n result.push(node);\n walkDescendants(store, row.name, node.children, visited, depth - 1);\n }\n}\n\n// ---------------------------------------------------------------------------\n// get_dead_exports\n// ---------------------------------------------------------------------------\n\nexport interface DeadExportItem {\n symbol_id: string;\n name: string;\n kind: string;\n file: string;\n line: number | null;\n}\n\nexport interface GetDeadExportsResult {\n file_pattern: string | null;\n dead_exports: DeadExportItem[];\n total_exports: number;\n total_dead: number;\n}\n\n/**\n * Find exported symbols that are never imported by any other file.\n * Cross-references exported symbols with import edge metadata (specifiers).\n * An export is \"dead\" if its name never appears as a specifier in any import edge.\n */\nexport function getDeadExports(\n store: Store,\n filePattern?: string,\n): GetDeadExportsResult {\n const exported = store.getExportedSymbols(filePattern);\n\n // Build a set of all imported specifier names across the entire project\n const importedNames = new Set<string>();\n const importEdges = store.getEdgesByType('imports');\n for (const edge of importEdges) {\n if (!edge.metadata) continue;\n const meta = typeof edge.metadata === 'string'\n ? JSON.parse(edge.metadata) as Record<string, unknown>\n : edge.metadata as Record<string, unknown>;\n const specifiers = meta['specifiers'];\n if (Array.isArray(specifiers)) {\n for (const s of specifiers) {\n if (typeof s === 'string') {\n // Handle \"* as name\" → add \"name\"\n const clean = s.startsWith('* as ') ? s.slice(5) : s;\n importedNames.add(clean);\n }\n }\n }\n }\n\n const dead: DeadExportItem[] = [];\n for (const sym of exported) {\n // Skip methods (their export is inherited from the class)\n if (sym.kind === 'method') continue;\n if (!importedNames.has(sym.name)) {\n dead.push({\n symbol_id: sym.symbol_id,\n name: sym.name,\n kind: sym.kind,\n file: sym.file_path,\n line: sym.line_start,\n });\n }\n }\n\n return {\n file_pattern: filePattern ?? null,\n dead_exports: dead,\n total_exports: exported.filter((s) => s.kind !== 'method').length,\n total_dead: dead.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// get_dependency_graph\n// ---------------------------------------------------------------------------\n\nexport interface DependencyEdge {\n source: string;\n target: string;\n specifiers: string[];\n}\n\nexport interface GetDependencyGraphResult {\n file: string;\n imports: DependencyEdge[];\n imported_by: DependencyEdge[];\n}\n\n/**\n * Show file-level dependency graph: what a file imports and what imports it.\n * Requires ESM import edges (resolved by the pipeline in Pass 2d).\n */\nexport function getDependencyGraph(\n store: Store,\n filePath: string,\n): GetDependencyGraphResult {\n const file = store.getFile(filePath);\n if (!file) {\n return { file: filePath, imports: [], imported_by: [] };\n }\n\n const nodeId = store.getNodeId('file', file.id);\n if (nodeId == null) {\n return { file: filePath, imports: [], imported_by: [] };\n }\n\n // Outgoing imports (what this file imports)\n const outgoing = store.getOutgoingEdges(nodeId)\n .filter((e) => e.edge_type_name === 'imports');\n const imports: DependencyEdge[] = [];\n for (const edge of outgoing) {\n const targetRef = store.getNodeRef(edge.target_node_id);\n if (!targetRef || targetRef.nodeType !== 'file') continue;\n const targetFile = store.getFileById(targetRef.refId);\n if (!targetFile) continue;\n const meta = edge.metadata\n ? (typeof edge.metadata === 'string' ? JSON.parse(edge.metadata) : edge.metadata) as Record<string, unknown>\n : {};\n imports.push({\n source: filePath,\n target: targetFile.path,\n specifiers: (meta['specifiers'] as string[]) ?? [],\n });\n }\n\n // Incoming imports (what imports this file)\n const incoming = store.getIncomingEdges(nodeId)\n .filter((e) => e.edge_type_name === 'imports');\n const importedBy: DependencyEdge[] = [];\n for (const edge of incoming) {\n const sourceRef = store.getNodeRef(edge.source_node_id);\n if (!sourceRef || sourceRef.nodeType !== 'file') continue;\n const sourceFile = store.getFileById(sourceRef.refId);\n if (!sourceFile) continue;\n const meta = edge.metadata\n ? (typeof edge.metadata === 'string' ? JSON.parse(edge.metadata) : edge.metadata) as Record<string, unknown>\n : {};\n importedBy.push({\n source: sourceFile.path,\n target: filePath,\n specifiers: (meta['specifiers'] as string[]) ?? [],\n });\n }\n\n return { file: filePath, imports, imported_by: importedBy };\n}\n\n// ---------------------------------------------------------------------------\n// get_untested_exports\n// ---------------------------------------------------------------------------\n\nexport interface UntestedExportItem {\n symbol_id: string;\n name: string;\n kind: string;\n file: string;\n line: number | null;\n signature: string | null;\n}\n\nexport interface GetUntestedExportsResult {\n file_pattern: string | null;\n untested: UntestedExportItem[];\n total_exports: number;\n total_untested: number;\n}\n\n/**\n * Find exported public symbols that have no associated test coverage.\n * Uses heuristic path matching: for each exported symbol, checks if any\n * test file in the project matches its file name or symbol name pattern.\n */\nexport function getUntestedExports(\n store: Store,\n filePattern?: string,\n): GetUntestedExportsResult {\n const exported = store.getExportedSymbols(filePattern)\n .filter((s) => s.kind !== 'method'); // methods inherit from class\n\n // Collect all test file paths\n const allFiles = store.getAllFiles();\n const testFiles = allFiles\n .filter((f) => /\\.(test|spec)\\.(ts|js|tsx|jsx)$/.test(f.path))\n .map((f) => f.path.toLowerCase());\n\n const untested: UntestedExportItem[] = [];\n\n for (const sym of exported) {\n // Normalize the source file name for matching\n const baseName = sym.file_path\n .replace(/\\.[^.]+$/, '') // strip extension\n .split('/').pop()! // get filename\n .toLowerCase();\n\n // Check if any test file references this source file\n const hasTest = testFiles.some((testPath) => {\n const testBase = testPath.split('/').pop()!;\n return (\n testBase.includes(baseName) ||\n testBase.includes(toKebab(sym.name))\n );\n });\n\n if (!hasTest) {\n untested.push({\n symbol_id: sym.symbol_id,\n name: sym.name,\n kind: sym.kind,\n file: sym.file_path,\n line: sym.line_start,\n signature: sym.signature,\n });\n }\n }\n\n return {\n file_pattern: filePattern ?? null,\n untested,\n total_exports: exported.length,\n total_untested: untested.length,\n };\n}\n\n/** Convert PascalCase/camelCase to kebab-case for test file matching */\nfunction toKebab(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')\n .toLowerCase();\n}\n\n// ---------------------------------------------------------------------------\n// self_audit\n// ---------------------------------------------------------------------------\n\nexport interface SelfAuditResult {\n summary: {\n total_files: number;\n total_symbols: number;\n total_edges: number;\n total_exports: number;\n dead_exports: number;\n untested_exports: number;\n test_files: number;\n import_edges: number;\n heritage_edges: number;\n test_covers_edges: number;\n };\n dead_exports_top10: DeadExportItem[];\n untested_top10: UntestedExportItem[];\n /** Files with most incoming import edges (most depended-on) */\n most_imported_files: { file: string; imported_by_count: number }[];\n /** Files with most outgoing import edges (most dependencies) */\n most_dependent_files: { file: string; imports_count: number }[];\n /** Interfaces/classes with the most implementors */\n widest_interfaces: { name: string; implementor_count: number }[];\n}\n\n/**\n * One-shot project health audit — combines dead exports, untested exports,\n * dependency hotspots, and heritage metrics into a single report.\n */\nexport function selfAudit(store: Store): SelfAuditResult {\n const stats = store.getStats();\n\n // Dead exports\n const deadResult = getDeadExports(store);\n\n // Untested exports\n const untestedResult = getUntestedExports(store);\n\n // Edge type counts\n const importEdges = store.getEdgesByType('imports');\n const heritageExtends = store.getEdgesByType('ts_extends');\n const heritageImplements = store.getEdgesByType('ts_implements');\n const testCovers = store.getEdgesByType('test_covers');\n\n // Test files count\n const allFiles = store.getAllFiles();\n const testFileCount = allFiles.filter((f) =>\n /\\.(test|spec)\\.[jt]sx?$|__tests__\\//.test(f.path),\n ).length;\n\n // Most imported files (incoming import edges per file)\n const importedByCount = new Map<number, number>();\n for (const edge of importEdges) {\n importedByCount.set(\n edge.target_node_id,\n (importedByCount.get(edge.target_node_id) ?? 0) + 1,\n );\n }\n const mostImported = [...importedByCount.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([nodeId, count]) => {\n const ref = store.getNodeRef(nodeId);\n const file = ref?.nodeType === 'file' ? store.getFileById(ref.refId) : undefined;\n return { file: file?.path ?? `[node:${nodeId}]`, imported_by_count: count };\n });\n\n // Most dependent files (outgoing import edges per file)\n const importsCount = new Map<number, number>();\n for (const edge of importEdges) {\n importsCount.set(\n edge.source_node_id,\n (importsCount.get(edge.source_node_id) ?? 0) + 1,\n );\n }\n const mostDependent = [...importsCount.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([nodeId, count]) => {\n const ref = store.getNodeRef(nodeId);\n const file = ref?.nodeType === 'file' ? store.getFileById(ref.refId) : undefined;\n return { file: file?.path ?? `[node:${nodeId}]`, imports_count: count };\n });\n\n // Widest interfaces (most implementors via heritage metadata)\n const allClassesAndInterfaces = store.db.prepare(\n \"SELECT name, kind FROM symbols WHERE kind IN ('class', 'interface') AND json_extract(metadata, '$.exported') = 1\",\n ).all() as { name: string; kind: string }[];\n\n const interfaceCounts: { name: string; implementor_count: number }[] = [];\n for (const sym of allClassesAndInterfaces) {\n if (sym.kind !== 'interface') continue;\n const impls = store.findImplementors(sym.name);\n if (impls.length > 0) {\n interfaceCounts.push({ name: sym.name, implementor_count: impls.length });\n }\n }\n interfaceCounts.sort((a, b) => b.implementor_count - a.implementor_count);\n\n return {\n summary: {\n total_files: stats.totalFiles,\n total_symbols: stats.totalSymbols,\n total_edges: stats.totalEdges,\n total_exports: deadResult.total_exports,\n dead_exports: deadResult.total_dead,\n untested_exports: untestedResult.total_untested,\n test_files: testFileCount,\n import_edges: importEdges.length,\n heritage_edges: heritageExtends.length + heritageImplements.length,\n test_covers_edges: testCovers.length,\n },\n dead_exports_top10: deadResult.dead_exports.slice(0, 10),\n untested_top10: untestedResult.untested.slice(0, 10),\n most_imported_files: mostImported,\n most_dependent_files: mostDependent,\n widest_interfaces: interfaceCounts.slice(0, 10),\n };\n}\n","/**\n * PHP Language Plugin — tree-sitter based symbol extraction.\n *\n * Extracts classes, methods, functions, interfaces, traits, enums,\n * constants, properties, and enum_cases from PHP source files.\n */\nimport { createRequire } from 'node:module';\nimport { ok, err } from 'neverthrow';\nimport type { LanguagePlugin, PluginManifest, FileParseResult, RawSymbol, SymbolKind } from '../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../errors.js';\nimport { parseError } from '../../../errors.js';\nimport {\n type TSNode,\n extractNamespace,\n makeSymbolId,\n makeFqn,\n extractSignature,\n extractAttributes,\n extractPromotedProperties,\n extractPropertySymbol,\n extractConstantSymbols,\n} from './php-helpers.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst PhpGrammar = require('tree-sitter-php');\n\nlet parserInstance: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(): InstanceType<typeof Parser> {\n if (!parserInstance) {\n parserInstance = new Parser();\n parserInstance!.setLanguage(PhpGrammar.php);\n }\n return parserInstance!;\n}\n\nexport class PhpLanguagePlugin implements LanguagePlugin {\n manifest: PluginManifest = {\n name: 'php-language',\n version: '1.0.0',\n priority: 0,\n };\n\n supportedExtensions = ['.php'];\n\n extractSymbols(filePath: string, content: Buffer): TraceMcpResult<FileParseResult> {\n try {\n const parser = getParser();\n const sourceCode = content.toString('utf-8');\n const tree = parser.parse(sourceCode);\n const root: TSNode = tree.rootNode;\n\n const hasError = root.hasError;\n const namespace = extractNamespace(root);\n const symbols: RawSymbol[] = [];\n const warnings: string[] = [];\n\n if (hasError) {\n warnings.push('Source contains syntax errors; extraction may be incomplete');\n }\n\n this.walkTopLevel(root, filePath, namespace, symbols);\n\n return ok({\n language: 'php',\n status: hasError ? 'partial' : 'ok',\n symbols,\n warnings: warnings.length > 0 ? warnings : undefined,\n });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return err(parseError(filePath, `PHP parse failed: ${msg}`));\n }\n }\n\n private walkTopLevel(root: TSNode, filePath: string, namespace: string | undefined, symbols: RawSymbol[]): void {\n for (const node of root.namedChildren) {\n switch (node.type) {\n case 'class_declaration':\n this.extractClass(node, filePath, namespace, symbols);\n break;\n case 'interface_declaration':\n this.extractClassLike(node, filePath, namespace, symbols, 'interface');\n break;\n case 'trait_declaration':\n this.extractClassLike(node, filePath, namespace, symbols, 'trait');\n break;\n case 'enum_declaration':\n this.extractEnum(node, filePath, namespace, symbols);\n break;\n case 'function_definition':\n this.extractFunction(node, filePath, namespace, symbols);\n break;\n // Handle namespace body (when namespace has a block)\n case 'namespace_definition': {\n const body = node.namedChildren.find(\n (c) => c.type === 'compound_statement' || c.type === 'declaration_list',\n );\n if (body) {\n const nsName = node.namedChildren.find((c) => c.type === 'namespace_name');\n const innerNs = nsName?.text ?? namespace;\n this.walkTopLevel(body, filePath, innerNs, symbols);\n }\n break;\n }\n }\n }\n }\n\n private extractClass(\n node: TSNode, filePath: string, namespace: string | undefined, symbols: RawSymbol[],\n ): void {\n const nameNode = node.childForFieldName('name');\n if (!nameNode) return;\n const className = nameNode.text;\n const symbolId = makeSymbolId(filePath, className, 'class');\n const attrs = extractAttributes(node);\n\n symbols.push({\n symbolId,\n name: className,\n kind: 'class',\n fqn: makeFqn(namespace, className),\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: attrs.length > 0 ? { attributes: attrs } : undefined,\n });\n\n const body = node.childForFieldName('body');\n if (body) {\n this.extractClassMembers(body, filePath, className, namespace, symbolId, symbols);\n }\n }\n\n private extractClassLike(\n node: TSNode, filePath: string, namespace: string | undefined,\n symbols: RawSymbol[], kind: 'interface' | 'trait',\n ): void {\n const nameNode = node.childForFieldName('name');\n if (!nameNode) return;\n const name = nameNode.text;\n const symbolId = makeSymbolId(filePath, name, kind);\n\n symbols.push({\n symbolId,\n name,\n kind,\n fqn: makeFqn(namespace, name),\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n });\n\n // For traits and interfaces, also extract methods\n const body = node.namedChildren.find((c) => c.type === 'declaration_list');\n if (body) {\n this.extractClassMembers(body, filePath, name, namespace, symbolId, symbols);\n }\n }\n\n private extractEnum(\n node: TSNode, filePath: string, namespace: string | undefined, symbols: RawSymbol[],\n ): void {\n const nameNode = node.childForFieldName('name');\n if (!nameNode) return;\n const name = nameNode.text;\n const symbolId = makeSymbolId(filePath, name, 'enum');\n\n symbols.push({\n symbolId,\n name,\n kind: 'enum',\n fqn: makeFqn(namespace, name),\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n });\n\n // Extract enum cases\n const body = node.namedChildren.find((c) => c.type === 'enum_declaration_list');\n if (body) {\n for (const child of body.namedChildren) {\n if (child.type === 'enum_case') {\n const caseName = child.childForFieldName('name')\n ?? child.namedChildren.find((c) => c.type === 'name');\n if (!caseName) continue;\n symbols.push({\n symbolId: makeSymbolId(filePath, caseName.text, 'enum_case', name),\n name: caseName.text,\n kind: 'enum_case',\n fqn: makeFqn(namespace, name, caseName.text),\n parentSymbolId: symbolId,\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n });\n }\n }\n }\n }\n\n private extractFunction(\n node: TSNode, filePath: string, namespace: string | undefined, symbols: RawSymbol[],\n ): void {\n const nameNode = node.childForFieldName('name');\n if (!nameNode) return;\n const name = nameNode.text;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'function'),\n name,\n kind: 'function',\n fqn: namespace ? `${namespace}\\\\${name}` : name,\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n });\n }\n\n private extractClassMembers(\n body: TSNode, filePath: string, className: string,\n namespace: string | undefined, classSymbolId: string, symbols: RawSymbol[],\n ): void {\n for (const child of body.namedChildren) {\n switch (child.type) {\n case 'method_declaration':\n this.extractMethod(child, filePath, className, namespace, classSymbolId, symbols);\n break;\n case 'property_declaration':\n this.extractProperty(child, filePath, className, namespace, classSymbolId, symbols);\n break;\n case 'const_declaration':\n this.extractConstant(child, filePath, className, namespace, classSymbolId, symbols);\n break;\n }\n }\n }\n\n private extractMethod(\n node: TSNode, filePath: string, className: string,\n namespace: string | undefined, classSymbolId: string, symbols: RawSymbol[],\n ): void {\n const nameNode = node.childForFieldName('name');\n if (!nameNode) return;\n const name = nameNode.text;\n const attrs = extractAttributes(node);\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'method', className),\n name,\n kind: 'method',\n fqn: makeFqn(namespace, className, name),\n parentSymbolId: classSymbolId,\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: attrs.length > 0 ? { attributes: attrs } : undefined,\n });\n\n // Extract constructor-promoted properties\n if (name === '__construct') {\n const promoted = extractPromotedProperties(node, filePath, className, namespace, classSymbolId);\n symbols.push(...promoted);\n }\n }\n\n private extractProperty(\n node: TSNode, filePath: string, className: string,\n namespace: string | undefined, classSymbolId: string, symbols: RawSymbol[],\n ): void {\n const sym = extractPropertySymbol(node, filePath, className, namespace, classSymbolId);\n if (sym) symbols.push(sym);\n }\n\n private extractConstant(\n node: TSNode, filePath: string, className: string,\n namespace: string | undefined, classSymbolId: string, symbols: RawSymbol[],\n ): void {\n symbols.push(...extractConstantSymbols(node, filePath, className, namespace, classSymbolId));\n }\n}\n","/**\n * Helper utilities for the PHP language plugin.\n * Extracts AST-walking logic to keep the main plugin under 300 lines.\n */\nimport type { RawSymbol, SymbolKind } from '../../../plugin-api/types.js';\n\n// tree-sitter types (CJS interop — no type package available)\ntype TSNode = {\n type: string;\n text: string;\n startIndex: number;\n endIndex: number;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n namedChildCount: number;\n childCount: number;\n namedChildren: TSNode[];\n namedChild(index: number): TSNode | null;\n child(index: number): TSNode | null;\n childForFieldName(name: string): TSNode | null;\n parent: TSNode | null;\n isNamed: boolean;\n hasError: boolean;\n};\n\nexport type { TSNode };\n\n/** Extract the namespace string from the root program node. */\nexport function extractNamespace(rootNode: TSNode): string | undefined {\n for (const child of rootNode.namedChildren) {\n if (child.type === 'namespace_definition') {\n const nsName = child.namedChildren.find((c) => c.type === 'namespace_name');\n if (nsName) return nsName.text;\n }\n }\n return undefined;\n}\n\n/** Build a symbol ID following the convention: `path::Name#kind` */\nexport function makeSymbolId(\n relativePath: string,\n name: string,\n kind: SymbolKind,\n parentName?: string,\n): string {\n if (parentName) {\n return `${relativePath}::${parentName}::${name}#${kind}`;\n }\n return `${relativePath}::${name}#${kind}`;\n}\n\n/** Build a fully qualified name. */\nexport function makeFqn(namespace: string | undefined, className: string, memberName?: string): string {\n const base = namespace ? `${namespace}\\\\${className}` : className;\n return memberName ? `${base}::${memberName}` : base;\n}\n\n/** Extract visibility + modifiers + function/class signature from source (first line only). */\nexport function extractSignature(node: TSNode): string {\n const firstLine = node.text.split('\\n')[0].trim();\n // Trim body openers: { or anything after {\n const braceIdx = firstLine.indexOf('{');\n if (braceIdx > 0) {\n return firstLine.substring(0, braceIdx).trim();\n }\n // For abstract/interface methods ending with ;\n const semiIdx = firstLine.indexOf(';');\n if (semiIdx > 0) {\n return firstLine.substring(0, semiIdx).trim();\n }\n return firstLine;\n}\n\n/** Check if a property_declaration has the readonly modifier. */\nexport function isReadonly(node: TSNode): boolean {\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n if (child && child.type === 'readonly_modifier') return true;\n }\n return false;\n}\n\n/** Extract attribute names from an attribute_list node. */\nexport function extractAttributes(node: TSNode): string[] {\n const attrs: string[] = [];\n for (const child of node.namedChildren) {\n if (child.type === 'attribute_list') {\n for (const group of child.namedChildren) {\n if (group.type === 'attribute_group') {\n for (const attr of group.namedChildren) {\n if (attr.type === 'attribute') {\n const name = attr.childForFieldName('name') ?? attr.namedChildren[0];\n if (name) attrs.push(name.text);\n }\n }\n }\n }\n }\n }\n return attrs;\n}\n\n/** Extract visibility modifier text from a node's children. */\nexport function getVisibility(node: TSNode): string | undefined {\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n if (child && child.type === 'visibility_modifier') return child.text;\n }\n return undefined;\n}\n\n/** Extract constructor-promoted parameters as property symbols. */\nexport function extractPromotedProperties(\n methodNode: TSNode,\n relativePath: string,\n className: string,\n namespace: string | undefined,\n classSymbolId: string,\n): RawSymbol[] {\n const params = methodNode.childForFieldName('parameters');\n if (!params) return [];\n\n const symbols: RawSymbol[] = [];\n for (const param of params.namedChildren) {\n if (param.type === 'property_promotion_parameter') {\n const varName = param.childForFieldName('name')\n ?? param.namedChildren.find((c) => c.type === 'variable_name');\n if (!varName) continue;\n const propName = varName.text.replace(/^\\$/, '');\n const readonly = isReadonly(param);\n const visibility = getVisibility(param);\n\n symbols.push({\n symbolId: makeSymbolId(relativePath, propName, 'property', className),\n name: propName,\n kind: 'property',\n fqn: makeFqn(namespace, className, propName),\n parentSymbolId: classSymbolId,\n signature: param.text.trim(),\n byteStart: param.startIndex,\n byteEnd: param.endIndex,\n lineStart: param.startPosition.row + 1,\n lineEnd: param.endPosition.row + 1,\n metadata: {\n ...(readonly ? { readonly: true } : {}),\n ...(visibility ? { visibility } : {}),\n promoted: true,\n },\n });\n }\n }\n return symbols;\n}\n\n/** Extract a property_declaration node into a RawSymbol. */\nexport function extractPropertySymbol(\n node: TSNode, filePath: string, className: string,\n namespace: string | undefined, classSymbolId: string,\n): RawSymbol | undefined {\n const propElement = node.namedChildren.find((c) => c.type === 'property_element');\n if (!propElement) return undefined;\n const varName = propElement.namedChildren.find((c) => c.type === 'variable_name');\n if (!varName) return undefined;\n const name = varName.text.replace(/^\\$/, '');\n const readonly = isReadonly(node);\n const visibility = getVisibility(node);\n\n return {\n symbolId: makeSymbolId(filePath, name, 'property', className),\n name,\n kind: 'property',\n fqn: makeFqn(namespace, className, name),\n parentSymbolId: classSymbolId,\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: {\n ...(readonly ? { readonly: true } : {}),\n ...(visibility ? { visibility } : {}),\n },\n };\n}\n\n/** Extract const_element children from a const_declaration node. */\nexport function extractConstantSymbols(\n node: TSNode, filePath: string, className: string,\n namespace: string | undefined, classSymbolId: string,\n): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n for (const child of node.namedChildren) {\n if (child.type === 'const_element') {\n const nameNode = child.childForFieldName('name')\n ?? child.namedChildren.find((c) => c.type === 'name');\n if (!nameNode) continue;\n const name = nameNode.text;\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'constant', className),\n name,\n kind: 'constant',\n fqn: makeFqn(namespace, className, name),\n parentSymbolId: classSymbolId,\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n });\n }\n }\n return symbols;\n}\n","/**\n * TypeScript/JavaScript Language Plugin — tree-sitter based symbol extraction.\n *\n * Extracts functions, classes, variables (exported const/let), types,\n * interfaces, enums, methods, and import edges from TS/JS source files.\n */\nimport { createRequire } from 'node:module';\nimport { ok, err } from 'neverthrow';\nimport type { LanguagePlugin, PluginManifest, FileParseResult, RawSymbol } from '../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../errors.js';\nimport { parseError } from '../../../errors.js';\nimport {\n type TSNode,\n makeSymbolId,\n getFullSignature,\n isExported,\n isDefaultExport,\n isAsync,\n getNodeName,\n extractImportEdges,\n extractClassMethods,\n} from './ts-helpers.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst TsGrammar = require('tree-sitter-typescript');\n\nlet tsParser: InstanceType<typeof Parser> | null = null;\nlet tsxParser: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(tsx: boolean): InstanceType<typeof Parser> {\n if (tsx) {\n if (!tsxParser) {\n tsxParser = new Parser();\n tsxParser!.setLanguage(TsGrammar.tsx);\n }\n return tsxParser!;\n }\n if (!tsParser) {\n tsParser = new Parser();\n tsParser!.setLanguage(TsGrammar.typescript);\n }\n return tsParser!;\n}\n\nconst TSX_EXTENSIONS = new Set(['.tsx', '.jsx']);\n\nexport class TypeScriptLanguagePlugin implements LanguagePlugin {\n manifest: PluginManifest = {\n name: 'typescript-language',\n version: '1.0.0',\n priority: 5,\n };\n\n supportedExtensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'];\n\n extractSymbols(filePath: string, content: Buffer): TraceMcpResult<FileParseResult> {\n try {\n const ext = filePath.substring(filePath.lastIndexOf('.'));\n const useTsx = TSX_EXTENSIONS.has(ext);\n const parser = getParser(useTsx);\n const sourceCode = content.toString('utf-8');\n const tree = parser.parse(sourceCode);\n const root: TSNode = tree.rootNode;\n\n const hasError = root.hasError;\n const symbols: RawSymbol[] = [];\n const warnings: string[] = [];\n\n if (hasError) {\n warnings.push('Source contains syntax errors; extraction may be incomplete');\n }\n\n this.walkTopLevel(root, filePath, symbols);\n\n const edges = extractImportEdges(root);\n\n return ok({\n language: 'typescript',\n status: hasError ? 'partial' : 'ok',\n symbols,\n edges: edges.length > 0 ? edges : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return err(parseError(filePath, `TypeScript parse failed: ${msg}`));\n }\n }\n\n private walkTopLevel(root: TSNode, filePath: string, symbols: RawSymbol[]): void {\n for (const node of root.namedChildren) {\n switch (node.type) {\n case 'function_declaration':\n this.extractFunction(node, filePath, symbols);\n break;\n case 'class_declaration':\n this.extractClass(node, filePath, symbols);\n break;\n case 'lexical_declaration':\n this.extractVariable(node, filePath, symbols);\n break;\n case 'type_alias_declaration':\n this.extractType(node, filePath, symbols);\n break;\n case 'interface_declaration':\n this.extractInterface(node, filePath, symbols);\n break;\n case 'enum_declaration':\n this.extractEnum(node, filePath, symbols);\n break;\n case 'export_statement':\n this.walkExportStatement(node, filePath, symbols);\n break;\n }\n }\n }\n\n private walkExportStatement(exportNode: TSNode, filePath: string, symbols: RawSymbol[]): void {\n for (const child of exportNode.namedChildren) {\n switch (child.type) {\n case 'function_declaration':\n this.extractFunction(child, filePath, symbols);\n break;\n case 'class_declaration':\n this.extractClass(child, filePath, symbols);\n break;\n case 'lexical_declaration':\n this.extractVariable(child, filePath, symbols);\n break;\n case 'type_alias_declaration':\n this.extractType(child, filePath, symbols);\n break;\n case 'interface_declaration':\n this.extractInterface(child, filePath, symbols);\n break;\n case 'enum_declaration':\n this.extractEnum(child, filePath, symbols);\n break;\n }\n }\n }\n\n private extractFunction(node: TSNode, filePath: string, symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'function'),\n name,\n kind: 'function',\n signature: getFullSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: {\n exported: isExported(node),\n default: isDefaultExport(node),\n async: isAsync(node),\n },\n });\n }\n\n private extractClass(node: TSNode, filePath: string, symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n const symbolId = makeSymbolId(filePath, name, 'class');\n\n const heritage = this.extractHeritage(node);\n\n symbols.push({\n symbolId,\n name,\n kind: 'class',\n signature: getFullSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: {\n exported: isExported(node),\n default: isDefaultExport(node),\n ...(heritage.extends ? { extends: heritage.extends } : {}),\n ...(heritage.implements.length > 0 ? { implements: heritage.implements } : {}),\n },\n });\n\n const body = node.childForFieldName('body');\n if (body) {\n symbols.push(...extractClassMethods(body, filePath, name, symbolId));\n }\n }\n\n private extractVariable(node: TSNode, filePath: string, symbols: RawSymbol[]): void {\n const exported = isExported(node);\n if (!exported) return; // Only extract exported variables\n\n for (const child of node.namedChildren) {\n if (child.type === 'variable_declarator') {\n const name = getNodeName(child);\n if (!name) continue;\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'variable'),\n name,\n kind: 'variable',\n signature: getFullSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: {\n exported: true,\n default: isDefaultExport(node),\n },\n });\n }\n }\n }\n\n private extractType(node: TSNode, filePath: string, symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'type'),\n name,\n kind: 'type',\n signature: getFullSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: {\n exported: isExported(node),\n default: isDefaultExport(node),\n },\n });\n }\n\n private extractInterface(node: TSNode, filePath: string, symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n\n const heritage = this.extractHeritage(node);\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'interface'),\n name,\n kind: 'interface',\n signature: getFullSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: {\n exported: isExported(node),\n default: isDefaultExport(node),\n ...(heritage.extends ? { extends: heritage.extends } : {}),\n ...(heritage.implements.length > 0 ? { implements: heritage.implements } : {}),\n },\n });\n }\n\n private extractHeritage(node: TSNode): { extends: string | null; implements: string[] } {\n const result: { extends: string | null; implements: string[] } = { extends: null, implements: [] };\n for (let i = 0; i < node.namedChildCount; i++) {\n const child = node.namedChild(i);\n if (!child) continue;\n\n if (child.type === 'class_heritage') {\n // class_heritage contains extends_clause and/or implements_clause\n for (const clause of child.namedChildren) {\n if (clause.type === 'extends_clause') {\n const typeNode = clause.namedChildren[0];\n if (typeNode) result.extends = typeNode.text;\n } else if (clause.type === 'implements_clause') {\n for (const impl of clause.namedChildren) {\n result.implements.push(impl.text);\n }\n }\n }\n } else if (child.type === 'extends_type_clause') {\n // interface Foo extends Bar, Baz\n for (const nc of child.namedChildren) {\n if (!result.extends) result.extends = nc.text;\n else result.implements.push(nc.text);\n }\n }\n }\n return result;\n }\n\n private extractEnum(node: TSNode, filePath: string, symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'enum'),\n name,\n kind: 'enum',\n signature: getFullSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: {\n exported: isExported(node),\n default: isDefaultExport(node),\n },\n });\n }\n}\n","/**\n * Helper utilities for the TypeScript language plugin.\n * Keeps the main plugin file under 300 lines.\n */\nimport type { RawSymbol, RawEdge, SymbolKind } from '../../../plugin-api/types.js';\n\n// Re-use the same TSNode type from the PHP helpers (tree-sitter CJS interop)\ntype TSNode = {\n type: string;\n text: string;\n startIndex: number;\n endIndex: number;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n namedChildCount: number;\n childCount: number;\n namedChildren: TSNode[];\n namedChild(index: number): TSNode | null;\n child(index: number): TSNode | null;\n childForFieldName(name: string): TSNode | null;\n parent: TSNode | null;\n isNamed: boolean;\n hasError: boolean;\n};\n\nexport type { TSNode };\n\n/** Build a symbol ID: `path::Name#kind` */\nexport function makeSymbolId(\n relativePath: string,\n name: string,\n kind: SymbolKind,\n parentName?: string,\n): string {\n if (parentName) {\n return `${relativePath}::${parentName}::${name}#${kind}`;\n }\n return `${relativePath}::${name}#${kind}`;\n}\n\n/** Extract signature (first line, trimmed of body). */\nexport function extractSignature(node: TSNode): string {\n const firstLine = node.text.split('\\n')[0].trim();\n const braceIdx = firstLine.indexOf('{');\n if (braceIdx > 0) {\n return firstLine.substring(0, braceIdx).trim();\n }\n const semiIdx = firstLine.indexOf(';');\n if (semiIdx > 0) {\n return firstLine.substring(0, semiIdx).trim();\n }\n return firstLine;\n}\n\n/** Check if a node is wrapped in an export statement. */\nexport function isExported(node: TSNode): boolean {\n const parent = node.parent;\n if (!parent) return false;\n return parent.type === 'export_statement';\n}\n\n/** Check if the export is a default export. */\nexport function isDefaultExport(node: TSNode): boolean {\n const parent = node.parent;\n if (!parent || parent.type !== 'export_statement') return false;\n for (let i = 0; i < parent.childCount; i++) {\n const child = parent.child(i);\n if (child && child.type === 'default') return true;\n }\n return false;\n}\n\n/** Check if a function/method node is async. */\nexport function isAsync(node: TSNode): boolean {\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n if (child && child.type === 'async') return true;\n }\n return false;\n}\n\n/** Get the full signature line including export prefix from the export_statement parent. */\nexport function getFullSignature(node: TSNode): string {\n const exported = isExported(node);\n const def = isDefaultExport(node);\n const base = extractSignature(node);\n\n const parts: string[] = [];\n if (exported) parts.push('export');\n if (def) parts.push('default');\n parts.push(base);\n return parts.join(' ');\n}\n\n/** Extract name from a declaration node. */\nexport function getNodeName(node: TSNode): string | undefined {\n const nameNode = node.childForFieldName('name');\n return nameNode?.text;\n}\n\n/** Extract import edges from the root of a TS/JS file. */\nexport function extractImportEdges(root: TSNode): RawEdge[] {\n const edges: RawEdge[] = [];\n for (const node of root.namedChildren) {\n if (node.type !== 'import_statement') continue;\n const source = node.childForFieldName('source');\n if (!source) continue;\n const from = source.text.replace(/^['\"]|['\"]$/g, '');\n\n const specifiers: string[] = [];\n for (const child of node.namedChildren) {\n if (child.type === 'import_clause') {\n for (const inner of child.namedChildren) {\n if (inner.type === 'identifier') {\n specifiers.push(inner.text);\n } else if (inner.type === 'named_imports') {\n for (const spec of inner.namedChildren) {\n if (spec.type === 'import_specifier') {\n const alias = spec.childForFieldName('alias');\n const name = spec.childForFieldName('name');\n specifiers.push(alias?.text ?? name?.text ?? spec.text);\n }\n }\n } else if (inner.type === 'namespace_import') {\n const id = inner.namedChildren.find((c) => c.type === 'identifier');\n if (id) specifiers.push(`* as ${id.text}`);\n }\n }\n }\n }\n\n edges.push({\n edgeType: 'imports',\n metadata: { from, specifiers },\n });\n }\n return edges;\n}\n\n/** Extract class methods from a class body. */\nexport function extractClassMethods(\n body: TSNode,\n filePath: string,\n className: string,\n classSymbolId: string,\n): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n for (const child of body.namedChildren) {\n if (child.type !== 'method_definition') continue;\n const name = getNodeName(child);\n if (!name) continue;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'method', className),\n name,\n kind: 'method',\n parentSymbolId: classSymbolId,\n signature: extractSignature(child),\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n metadata: {\n async: isAsync(child),\n },\n });\n }\n return symbols;\n}\n","/**\n * Vue SFC Language Plugin — extracts symbols from .vue single-file components.\n *\n * Uses @vue/compiler-sfc to parse the SFC descriptor, then:\n * - Extracts props, emits, exposed, composables from <script setup>\n * - Parses <script> blocks with tree-sitter-typescript for symbol extraction\n * - Extracts custom component tags from <template>\n */\nimport { createRequire } from 'node:module';\nimport { parse as parseSFC } from '@vue/compiler-sfc';\nimport { ok, err } from 'neverthrow';\nimport type {\n LanguagePlugin,\n PluginManifest,\n FileParseResult,\n RawSymbol,\n RawEdge,\n RawComponent,\n} from '../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../errors.js';\nimport { parseError } from '../../../errors.js';\nimport {\n type TSNode,\n makeSymbolId,\n extractImportEdges,\n} from './ts-helpers.js';\nimport {\n componentNameFromPath,\n extractProps,\n extractEmits,\n extractExposed,\n extractComposables,\n extractTemplateComponents,\n} from './vue-helpers.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst TsGrammar = require('tree-sitter-typescript');\n\nlet tsParser: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(): InstanceType<typeof Parser> {\n if (!tsParser) {\n tsParser = new Parser();\n tsParser.setLanguage(TsGrammar.typescript);\n }\n return tsParser;\n}\n\nexport class VueLanguagePlugin implements LanguagePlugin {\n manifest: PluginManifest = {\n name: 'vue-language',\n version: '1.0.0',\n priority: 10,\n };\n\n supportedExtensions = ['.vue'];\n\n extractSymbols(filePath: string, content: Buffer): TraceMcpResult<FileParseResult> {\n try {\n const sourceCode = content.toString('utf-8');\n const { descriptor, errors } = parseSFC(sourceCode, {\n filename: filePath,\n });\n\n const warnings: string[] = [];\n const symbols: RawSymbol[] = [];\n const edges: RawEdge[] = [];\n let status: 'ok' | 'partial' = 'ok';\n\n if (errors.length > 0) {\n status = 'partial';\n warnings.push(`SFC parse errors: ${errors.map((e) => e.message).join('; ')}`);\n }\n\n const componentName = componentNameFromPath(filePath);\n const componentSymbolId = makeSymbolId(filePath, componentName, 'class');\n\n // Create the component-level symbol\n symbols.push({\n symbolId: componentSymbolId,\n name: componentName,\n kind: 'class',\n byteStart: 0,\n byteEnd: content.length,\n lineStart: 1,\n lineEnd: sourceCode.split('\\n').length,\n metadata: {\n framework: 'vue',\n sfc: true,\n },\n });\n\n // Extract from <script setup>\n let props: string[] = [];\n let emits: string[] = [];\n let exposed: string[] = [];\n let composables: string[] = [];\n\n if (descriptor.scriptSetup) {\n const setupContent = descriptor.scriptSetup.content;\n props = extractProps(setupContent);\n emits = extractEmits(setupContent);\n exposed = extractExposed(setupContent);\n composables = extractComposables(setupContent);\n\n // Extract import edges from script setup via tree-sitter\n const setupEdges = this.parseScriptEdges(setupContent);\n edges.push(...setupEdges);\n }\n\n // Extract from <script> (Options API or regular)\n if (descriptor.script) {\n const scriptContent = descriptor.script.content;\n const scriptSymbols = this.parseScriptSymbols(scriptContent, filePath);\n symbols.push(...scriptSymbols);\n\n const scriptEdges = this.parseScriptEdges(scriptContent);\n edges.push(...scriptEdges);\n }\n\n // Extract template components\n let templateComponents: string[] = [];\n if (descriptor.template) {\n templateComponents = extractTemplateComponents(descriptor.template.content);\n }\n\n // Store template components + composables in component symbol metadata\n if (templateComponents.length > 0 || composables.length > 0) {\n const meta = symbols[0].metadata as Record<string, unknown>;\n if (templateComponents.length > 0) meta.templateComponents = templateComponents;\n if (composables.length > 0) meta.composables = composables;\n if (props.length > 0) meta.props = props;\n if (emits.length > 0) meta.emits = emits;\n if (exposed.length > 0) meta.exposed = exposed;\n }\n\n // Build the RawComponent\n const component: RawComponent = {\n name: componentName,\n kind: 'component',\n framework: 'vue',\n ...(props.length > 0 && {\n props: Object.fromEntries(props.map((p) => [p, { type: 'unknown' }])),\n }),\n ...(emits.length > 0 && { emits }),\n ...(composables.length > 0 && { composables }),\n };\n\n return ok({\n language: 'vue',\n status,\n symbols,\n edges: edges.length > 0 ? edges : undefined,\n components: [component],\n warnings: warnings.length > 0 ? warnings : undefined,\n });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return err(parseError(filePath, `Vue SFC parse failed: ${msg}`));\n }\n }\n\n /**\n * Parse a script block with tree-sitter to extract import edges.\n */\n private parseScriptEdges(scriptContent: string): RawEdge[] {\n try {\n const parser = getParser();\n const tree = parser.parse(scriptContent);\n return extractImportEdges(tree.rootNode as TSNode);\n } catch {\n return [];\n }\n }\n\n /**\n * Parse a <script> block with tree-sitter to extract top-level symbols.\n * Used for Options API / non-setup scripts.\n */\n private parseScriptSymbols(scriptContent: string, filePath: string): RawSymbol[] {\n try {\n const parser = getParser();\n const tree = parser.parse(scriptContent);\n const root: TSNode = tree.rootNode;\n const symbols: RawSymbol[] = [];\n\n for (const node of root.namedChildren) {\n if (node.type === 'export_statement') {\n for (const child of node.namedChildren) {\n if (child.type === 'object' || child.type === 'call_expression') {\n // export default { ... } — Options API component definition\n // We don't double-extract as the SFC itself is the component\n continue;\n }\n this.extractScriptNode(child, filePath, symbols);\n }\n } else {\n this.extractScriptNode(node, filePath, symbols);\n }\n }\n return symbols;\n } catch {\n return [];\n }\n }\n\n private extractScriptNode(node: TSNode, filePath: string, symbols: RawSymbol[]): void {\n const nameNode = node.childForFieldName('name');\n const name = nameNode?.text;\n if (!name) return;\n\n let kind: 'function' | 'class' | 'variable' | 'type' | 'interface' | 'enum' | undefined;\n switch (node.type) {\n case 'function_declaration':\n kind = 'function';\n break;\n case 'class_declaration':\n kind = 'class';\n break;\n case 'lexical_declaration':\n case 'variable_declarator':\n kind = 'variable';\n break;\n case 'type_alias_declaration':\n kind = 'type';\n break;\n case 'interface_declaration':\n kind = 'interface';\n break;\n case 'enum_declaration':\n kind = 'enum';\n break;\n }\n\n if (!kind) return;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, kind),\n name,\n kind,\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n });\n }\n}\n","/**\n * Helper utilities for the Vue SFC language plugin.\n * Extracts props, emits, exposed keys, composables, and template components.\n */\n\n/** HTML elements to exclude when detecting custom components in templates. */\nconst HTML_ELEMENTS = new Set([\n 'a', 'abbr', 'address', 'area', 'article', 'aside', 'audio', 'b', 'base',\n 'bdi', 'bdo', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption',\n 'cite', 'code', 'col', 'colgroup', 'data', 'datalist', 'dd', 'del',\n 'details', 'dfn', 'dialog', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset',\n 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5',\n 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'img',\n 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'link', 'main', 'map',\n 'mark', 'menu', 'meta', 'meter', 'nav', 'noscript', 'object', 'ol',\n 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q',\n 'rp', 'rt', 'ruby', 's', 'samp', 'script', 'search', 'section', 'select',\n 'slot', 'small', 'source', 'span', 'strong', 'style', 'sub', 'summary',\n 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th',\n 'thead', 'time', 'title', 'tr', 'track', 'u', 'ul', 'var', 'video', 'wbr',\n]);\n\n/** SVG elements to exclude. */\nconst SVG_ELEMENTS = new Set([\n 'svg', 'circle', 'clipPath', 'defs', 'desc', 'ellipse', 'feBlend',\n 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix',\n 'feDiffuseLighting', 'feDisplacementMap', 'feFlood', 'feFuncA', 'feFuncB',\n 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge',\n 'feMergeNode', 'feMorphology', 'feOffset', 'feSpecularLighting',\n 'feTile', 'feTurbulence', 'filter', 'foreignObject', 'g', 'image',\n 'line', 'linearGradient', 'marker', 'mask', 'path', 'pattern', 'polygon',\n 'polyline', 'radialGradient', 'rect', 'stop', 'switch', 'symbol', 'text',\n 'textPath', 'tspan', 'use', 'view',\n]);\n\n/** Vue built-in components / directives. */\nconst VUE_BUILTINS = new Set([\n 'component', 'transition', 'transition-group', 'keep-alive', 'teleport',\n 'suspense', 'Transition', 'TransitionGroup', 'KeepAlive', 'Teleport',\n 'Suspense', 'Component', 'RouterView', 'RouterLink', 'router-view',\n 'router-link',\n]);\n\n/**\n * Check if a tag name is a custom component (not HTML built-in).\n * Custom components are PascalCase or kebab-case with a hyphen.\n */\nexport function isCustomComponent(tag: string): boolean {\n if (VUE_BUILTINS.has(tag)) return false;\n if (HTML_ELEMENTS.has(tag.toLowerCase())) return false;\n if (SVG_ELEMENTS.has(tag)) return false;\n\n // PascalCase: starts with uppercase\n if (/^[A-Z]/.test(tag)) return true;\n // kebab-case with hyphen (custom elements must contain a hyphen)\n if (tag.includes('-')) return true;\n\n return false;\n}\n\n/**\n * Extract component tags from template content using regex.\n * Finds both self-closing and opening tags.\n */\nexport function extractTemplateComponents(templateContent: string): string[] {\n const tags = new Set<string>();\n // Match opening tags: <TagName or <tag-name\n const tagRegex = /<([A-Z][A-Za-z0-9]*|[a-z][a-z0-9]*(?:-[a-z0-9]+)+)/g;\n let match: RegExpExecArray | null;\n while ((match = tagRegex.exec(templateContent)) !== null) {\n const tag = match[1];\n if (isCustomComponent(tag)) {\n tags.add(tag);\n }\n }\n return [...tags];\n}\n\n/**\n * Extract prop names from defineProps calls in script setup content.\n * Handles:\n * - defineProps<{ name: type, ... }>()\n * - defineProps({ name: { type: ... } })\n * - defineProps(['name1', 'name2'])\n */\nexport function extractProps(scriptContent: string): string[] {\n const props: string[] = [];\n\n // Type-based: defineProps<{ prop: type; ... }>()\n const typeMatch = scriptContent.match(/defineProps\\s*<\\s*\\{([^}]+)\\}\\s*>/);\n if (typeMatch) {\n const body = typeMatch[1];\n // Match property names: `name:` or `name?:`\n const propNames = body.match(/(\\w+)\\s*[?]?\\s*:/g);\n if (propNames) {\n for (const p of propNames) {\n props.push(p.replace(/\\s*[?]?\\s*:/, ''));\n }\n }\n return props;\n }\n\n // Array-based: defineProps(['name1', 'name2'])\n const arrayMatch = scriptContent.match(/defineProps\\s*\\(\\s*\\[([^\\]]+)\\]/);\n if (arrayMatch) {\n const items = arrayMatch[1].match(/['\"](\\w+)['\"]/g);\n if (items) {\n for (const item of items) {\n props.push(item.replace(/['\"]/g, ''));\n }\n }\n return props;\n }\n\n // Object-based: defineProps({ name: { type: String }, name2: String })\n const objectMatch = scriptContent.match(/defineProps\\s*\\(\\s*\\{([^)]+)\\}/);\n if (objectMatch) {\n const body = objectMatch[1];\n const propNames = body.match(/(\\w+)\\s*:/g);\n if (propNames) {\n for (const p of propNames) {\n const name = p.replace(/\\s*:/, '');\n // Skip type/default/required/validator which are prop option keys\n if (!['type', 'default', 'required', 'validator'].includes(name)) {\n props.push(name);\n }\n }\n }\n return props;\n }\n\n return props;\n}\n\n/**\n * Extract emit names from defineEmits calls.\n * Handles:\n * - defineEmits<{ (e: 'name', ...): void }>()\n * - defineEmits(['name1', 'name2'])\n */\nexport function extractEmits(scriptContent: string): string[] {\n const emits: string[] = [];\n\n // Type-based: defineEmits<{ (e: 'name', ...): void }>()\n const typeMatch = scriptContent.match(/defineEmits\\s*<\\s*\\{([^}]+)\\}\\s*>/);\n if (typeMatch) {\n const body = typeMatch[1];\n const eventNames = body.match(/['\"](\\w+)['\"]/g);\n if (eventNames) {\n for (const name of eventNames) {\n emits.push(name.replace(/['\"]/g, ''));\n }\n }\n return emits;\n }\n\n // Array-based: defineEmits(['name1', 'name2'])\n const arrayMatch = scriptContent.match(/defineEmits\\s*\\(\\s*\\[([^\\]]+)\\]/);\n if (arrayMatch) {\n const items = arrayMatch[1].match(/['\"](\\w+)['\"]/g);\n if (items) {\n for (const item of items) {\n emits.push(item.replace(/['\"]/g, ''));\n }\n }\n return emits;\n }\n\n return emits;\n}\n\n/**\n * Extract exposed keys from defineExpose({ key1, key2 }).\n */\nexport function extractExposed(scriptContent: string): string[] {\n const match = scriptContent.match(/defineExpose\\s*\\(\\s*\\{([^}]+)\\}/);\n if (!match) return [];\n\n const body = match[1];\n const keys: string[] = [];\n // Match shorthand properties and key: value pairs\n const propPattern = /(\\w+)\\s*(?:,|$|\\s*:)/g;\n let m: RegExpExecArray | null;\n while ((m = propPattern.exec(body)) !== null) {\n keys.push(m[1]);\n }\n return keys;\n}\n\n/**\n * Detect composable usage: function calls matching use[A-Z]\\w+.\n */\nexport function extractComposables(scriptContent: string): string[] {\n const composables = new Set<string>();\n const pattern = /\\buse[A-Z]\\w+/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(scriptContent)) !== null) {\n composables.add(match[0]);\n }\n return [...composables];\n}\n\n/**\n * Derive component name from file path.\n * e.g., 'src/components/UserCard.vue' → 'UserCard'\n */\nexport function componentNameFromPath(filePath: string): string {\n const fileName = filePath.split('/').pop() ?? filePath;\n return fileName.replace(/\\.vue$/, '');\n}\n","/**\n * Python Language Plugin — tree-sitter based symbol extraction.\n *\n * Extracts classes, methods, functions, constants, variables, properties,\n * decorators, and import edges from Python source files.\n */\nimport { createRequire } from 'node:module';\nimport { ok, err } from 'neverthrow';\nimport type { LanguagePlugin, PluginManifest, FileParseResult, RawSymbol, SymbolKind } from '../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../errors.js';\nimport { parseError } from '../../../errors.js';\nimport {\n type TSNode,\n makeSymbolId,\n makeFqn,\n filePathToModule,\n extractSignature,\n extractDecorators,\n extractImportEdges,\n getNodeName,\n isAllCaps,\n extractClassBases,\n extractClassMethods,\n extractInstanceAttributes,\n} from './python-helpers.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst PythonGrammar = require('tree-sitter-python');\n\nlet parserInstance: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(): InstanceType<typeof Parser> {\n if (!parserInstance) {\n parserInstance = new Parser();\n parserInstance!.setLanguage(PythonGrammar);\n }\n return parserInstance!;\n}\n\nexport class PythonLanguagePlugin implements LanguagePlugin {\n manifest: PluginManifest = {\n name: 'python-language',\n version: '1.0.0',\n priority: 5,\n };\n\n supportedExtensions = ['.py', '.pyi'];\n\n extractSymbols(filePath: string, content: Buffer): TraceMcpResult<FileParseResult> {\n try {\n const parser = getParser();\n const sourceCode = content.toString('utf-8');\n const tree = parser.parse(sourceCode);\n const root: TSNode = tree.rootNode;\n\n const hasError = root.hasError;\n const modulePath = filePathToModule(filePath);\n const symbols: RawSymbol[] = [];\n const warnings: string[] = [];\n\n if (hasError) {\n warnings.push('Source contains syntax errors; extraction may be incomplete');\n }\n\n this.walkTopLevel(root, filePath, modulePath, symbols);\n\n const edges = extractImportEdges(root);\n\n return ok({\n language: 'python',\n status: hasError ? 'partial' : 'ok',\n symbols,\n edges: edges.length > 0 ? edges : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return err(parseError(filePath, `Python parse failed: ${msg}`));\n }\n }\n\n private walkTopLevel(\n root: TSNode,\n filePath: string,\n modulePath: string,\n symbols: RawSymbol[],\n ): void {\n for (const node of root.namedChildren) {\n switch (node.type) {\n case 'function_definition':\n this.extractFunction(node, filePath, modulePath, symbols, []);\n break;\n case 'class_definition':\n this.extractClass(node, filePath, modulePath, symbols, []);\n break;\n case 'decorated_definition':\n this.extractDecorated(node, filePath, modulePath, symbols);\n break;\n case 'expression_statement':\n this.extractModuleVariable(node, filePath, modulePath, symbols);\n break;\n }\n }\n }\n\n private extractDecorated(\n node: TSNode,\n filePath: string,\n modulePath: string,\n symbols: RawSymbol[],\n ): void {\n const decorators = extractDecorators(node);\n\n // Find the inner definition\n for (const child of node.namedChildren) {\n if (child.type === 'function_definition') {\n this.extractFunction(child, filePath, modulePath, symbols, decorators, node);\n return;\n }\n if (child.type === 'class_definition') {\n this.extractClass(child, filePath, modulePath, symbols, decorators, node);\n return;\n }\n }\n }\n\n private extractFunction(\n node: TSNode,\n filePath: string,\n modulePath: string,\n symbols: RawSymbol[],\n decorators: string[],\n rangeNode?: TSNode,\n ): void {\n const name = getNodeName(node);\n if (!name) return;\n\n const asyncFlag = node.text.trimStart().startsWith('async');\n const fqn = makeFqn([modulePath, name]);\n const effectiveNode = rangeNode ?? node;\n\n const meta: Record<string, unknown> = {};\n if (asyncFlag) meta.async = true;\n if (decorators.length > 0) meta.decorators = decorators;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'function'),\n name,\n kind: 'function',\n fqn,\n signature: extractSignature(node),\n byteStart: effectiveNode.startIndex,\n byteEnd: effectiveNode.endIndex,\n lineStart: effectiveNode.startPosition.row + 1,\n lineEnd: effectiveNode.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n }\n\n private extractClass(\n node: TSNode,\n filePath: string,\n modulePath: string,\n symbols: RawSymbol[],\n decorators: string[],\n rangeNode?: TSNode,\n ): void {\n const name = getNodeName(node);\n if (!name) return;\n\n const symbolId = makeSymbolId(filePath, name, 'class');\n const fqn = makeFqn([modulePath, name]);\n const bases = extractClassBases(node);\n const effectiveNode = rangeNode ?? node;\n\n const meta: Record<string, unknown> = {};\n if (decorators.length > 0) meta.decorators = decorators;\n if (bases.length > 0) meta.bases = bases;\n\n // Detect special class patterns\n if (decorators.includes('dataclass') || decorators.includes('dataclasses.dataclass')) {\n meta.dataclass = true;\n }\n if (bases.some((b) => b === 'BaseModel' || b.endsWith('.BaseModel'))) {\n meta.pydantic = true;\n }\n if (bases.some((b) => b === 'Protocol' || b.endsWith('.Protocol'))) {\n meta.protocol = true;\n }\n if (bases.some((b) => b === 'ABC' || b === 'ABCMeta' || b.endsWith('.ABC'))) {\n meta.abstract = true;\n }\n if (bases.some((b) => b === 'Enum' || b === 'IntEnum' || b === 'StrEnum' || b.endsWith('.Enum'))) {\n meta.enum = true;\n }\n\n symbols.push({\n symbolId,\n name,\n kind: 'class',\n fqn,\n signature: extractSignature(node),\n byteStart: effectiveNode.startIndex,\n byteEnd: effectiveNode.endIndex,\n lineStart: effectiveNode.startPosition.row + 1,\n lineEnd: effectiveNode.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n\n // Extract class body\n const body = node.childForFieldName('body');\n if (body) {\n // Extract methods\n const methods = extractClassMethods(body, filePath, name, symbolId);\n for (const method of methods) {\n method.fqn = makeFqn([modulePath, name, method.name]);\n symbols.push(method);\n }\n\n // Extract class-level variable assignments (class attributes)\n this.extractClassAttributes(body, filePath, modulePath, name, symbolId, symbols);\n\n // Extract instance attributes from __init__ (skip if already declared as class attr)\n const initMethod = this.findInitMethod(body);\n if (initMethod) {\n const initBody = initMethod.childForFieldName('body');\n if (initBody) {\n const attrs = extractInstanceAttributes(initBody, filePath, name, symbolId);\n for (const attr of attrs) {\n const exists = symbols.some(\n (s) => s.parentSymbolId === symbolId && s.name === attr.name,\n );\n if (!exists) {\n attr.fqn = makeFqn([modulePath, name, attr.name]);\n symbols.push(attr);\n }\n }\n }\n }\n }\n }\n\n /** Find the __init__ method in a class body (handles decorated_definition too). */\n private findInitMethod(body: TSNode): TSNode | null {\n for (const child of body.namedChildren) {\n if (child.type === 'function_definition') {\n if (getNodeName(child) === '__init__') return child;\n }\n if (child.type === 'decorated_definition') {\n const inner = child.namedChildren.find((c) => c.type === 'function_definition');\n if (inner && getNodeName(inner) === '__init__') return inner;\n }\n }\n return null;\n }\n\n /** Extract class-level attribute assignments (not methods). */\n private extractClassAttributes(\n body: TSNode,\n filePath: string,\n modulePath: string,\n className: string,\n classSymbolId: string,\n symbols: RawSymbol[],\n ): void {\n for (const child of body.namedChildren) {\n if (child.type !== 'expression_statement') continue;\n const expr = child.namedChildren[0];\n if (!expr) continue;\n\n if (expr.type === 'assignment') {\n const left = expr.childForFieldName('left');\n if (left && left.type === 'identifier') {\n const name = left.text;\n const kind: SymbolKind = isAllCaps(name) ? 'constant' : 'property';\n symbols.push({\n symbolId: makeSymbolId(filePath, name, kind, className),\n name,\n kind,\n fqn: makeFqn([modulePath, className, name]),\n parentSymbolId: classSymbolId,\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n });\n }\n }\n // Typed assignment: x: int = 5 or x: int (type annotation)\n if (expr.type === 'type') {\n // type alias node in tree-sitter-python; skip\n continue;\n }\n }\n\n // Handle typed assignments (annotation): `name: type` or `name: type = value`\n for (const child of body.namedChildren) {\n if (child.type !== 'expression_statement') continue;\n const expr = child.namedChildren[0];\n if (!expr) continue;\n\n if (expr.type === 'type' && expr.namedChildren.length > 0) {\n // annotated assignment without value: `x: int`\n const innerAssign = expr.namedChildren[0];\n if (innerAssign && innerAssign.type === 'identifier') {\n const name = innerAssign.text;\n const kind: SymbolKind = isAllCaps(name) ? 'constant' : 'property';\n // Avoid duplicates if already added as assignment\n const exists = symbols.some(\n (s) => s.parentSymbolId === classSymbolId && s.name === name,\n );\n if (!exists) {\n symbols.push({\n symbolId: makeSymbolId(filePath, name, kind, className),\n name,\n kind,\n fqn: makeFqn([modulePath, className, name]),\n parentSymbolId: classSymbolId,\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n });\n }\n }\n }\n }\n }\n\n /** Extract module-level variable/constant from an expression_statement. */\n private extractModuleVariable(\n node: TSNode,\n filePath: string,\n modulePath: string,\n symbols: RawSymbol[],\n ): void {\n const expr = node.namedChildren[0];\n if (!expr) return;\n\n if (expr.type === 'assignment') {\n const left = expr.childForFieldName('left');\n if (left && left.type === 'identifier') {\n const name = left.text;\n const kind: SymbolKind = isAllCaps(name) ? 'constant' : 'variable';\n const sig = node.text.split('\\n')[0].trim().slice(0, 80);\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, kind),\n name,\n kind,\n fqn: makeFqn([modulePath, name]),\n signature: sig,\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n });\n }\n // Handle tuple unpacking: a, b = 1, 2\n if (left && left.type === 'pattern_list') {\n for (const id of left.namedChildren) {\n if (id.type === 'identifier') {\n const name = id.text;\n const kind: SymbolKind = isAllCaps(name) ? 'constant' : 'variable';\n symbols.push({\n symbolId: makeSymbolId(filePath, name, kind),\n name,\n kind,\n fqn: makeFqn([modulePath, name]),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n });\n }\n }\n }\n }\n }\n}\n","/**\n * Helper utilities for the Python language plugin.\n * Extracts AST-walking logic to keep the main plugin under 300 lines.\n */\nimport type { RawSymbol, RawEdge, SymbolKind } from '../../../plugin-api/types.js';\n\n// tree-sitter types (CJS interop — no type package available)\ntype TSNode = {\n type: string;\n text: string;\n startIndex: number;\n endIndex: number;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n namedChildCount: number;\n childCount: number;\n namedChildren: TSNode[];\n namedChild(index: number): TSNode | null;\n child(index: number): TSNode | null;\n childForFieldName(name: string): TSNode | null;\n parent: TSNode | null;\n isNamed: boolean;\n hasError: boolean;\n};\n\nexport type { TSNode };\n\n/** Build a symbol ID following the convention: `path::Name#kind` */\nexport function makeSymbolId(\n relativePath: string,\n name: string,\n kind: SymbolKind,\n parentName?: string,\n): string {\n if (parentName) {\n return `${relativePath}::${parentName}::${name}#${kind}`;\n }\n return `${relativePath}::${name}#${kind}`;\n}\n\n/**\n * Build a dotted fully-qualified name for a Python symbol.\n * Converts file path to module notation: `src/foo/bar.py` → `src.foo.bar`\n * Handles `__init__.py` → package name (strip the file).\n */\nexport function makeFqn(parts: string[]): string {\n return parts.join('.');\n}\n\n/** Convert a file path to a Python module path. */\nexport function filePathToModule(filePath: string): string {\n let module = filePath\n .replace(/\\\\/g, '/')\n .replace(/\\.pyi?$/, '');\n // __init__ → use parent package\n if (module.endsWith('/__init__')) {\n module = module.slice(0, -'/__init__'.length);\n }\n return module.replace(/\\//g, '.');\n}\n\n/** Extract signature (first line, trimmed of body colon). */\nexport function extractSignature(node: TSNode): string {\n const firstLine = node.text.split('\\n')[0].trim();\n // For Python, trim trailing `:` and anything after it if it's a block opener\n const colonIdx = firstLine.lastIndexOf(':');\n if (colonIdx > 0) {\n return firstLine.substring(0, colonIdx).trim();\n }\n return firstLine;\n}\n\n/** Extract decorator names from a `decorated_definition` node's decorator children. */\nexport function extractDecorators(node: TSNode): string[] {\n const decorators: string[] = [];\n for (const child of node.namedChildren) {\n if (child.type === 'decorator') {\n // The decorator node contains an expression — usually identifier or call or attribute\n const expr = child.namedChildren[0];\n if (expr) {\n if (expr.type === 'identifier') {\n decorators.push(expr.text);\n } else if (expr.type === 'call') {\n const fn = expr.childForFieldName('function');\n if (fn) decorators.push(fn.text);\n } else if (expr.type === 'attribute') {\n decorators.push(expr.text);\n } else {\n decorators.push(expr.text);\n }\n }\n }\n }\n return decorators;\n}\n\n/**\n * Extract import edges from the root module node.\n *\n * - `import os.path` → { edgeType: 'py_imports', metadata: { from: 'os.path', specifiers: ['os'] } }\n * - `from myapp.models import User` → { from: 'myapp.models', specifiers: ['User'] }\n * - `from . import utils` → { from: '.', specifiers: ['utils'], relative: true }\n * - `from ..foo import bar` → { from: '..foo', specifiers: ['bar'], relative: true }\n */\nexport function extractImportEdges(root: TSNode): RawEdge[] {\n const edges: RawEdge[] = [];\n\n for (const node of root.namedChildren) {\n if (node.type === 'import_statement') {\n // `import os.path` or `import os.path as osp`\n for (const child of node.namedChildren) {\n if (child.type === 'dotted_name') {\n const moduleName = child.text;\n const topLevel = moduleName.split('.')[0];\n edges.push({\n edgeType: 'py_imports',\n metadata: { from: moduleName, specifiers: [topLevel] },\n });\n } else if (child.type === 'aliased_import') {\n const nameNode = child.childForFieldName('name') ?? child.namedChildren[0];\n const aliasNode = child.childForFieldName('alias');\n if (nameNode) {\n const moduleName = nameNode.text;\n const alias = aliasNode?.text ?? moduleName.split('.')[0];\n edges.push({\n edgeType: 'py_imports',\n metadata: { from: moduleName, specifiers: [alias] },\n });\n }\n }\n }\n } else if (node.type === 'import_from_statement') {\n // `from foo.bar import X, Y` or `from . import utils`\n const moduleNode = node.childForFieldName('module_name');\n\n // Collect dots for relative imports\n let dots = '';\n let moduleName = '';\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n if (!child) continue;\n if (child.type === 'relative_import') {\n // relative_import contains dots and optional dotted_name\n for (const rc of child.namedChildren) {\n if (rc.type === 'dotted_name') {\n moduleName = rc.text;\n } else if (rc.type === 'import_prefix') {\n dots = rc.text;\n }\n }\n // If no named children found for dots, count dots from text\n if (!dots) {\n const dotMatch = child.text.match(/^(\\.+)/);\n if (dotMatch) dots = dotMatch[1];\n // Get the module part after dots\n const afterDots = child.text.slice(dots.length).trim();\n if (afterDots && !moduleName) moduleName = afterDots;\n }\n break;\n }\n }\n\n // If no relative import, look for dotted_name as the module directly\n if (!dots && !moduleName && moduleNode) {\n moduleName = moduleNode.text;\n }\n if (!dots && !moduleName) {\n // Try to find dotted_name child directly\n for (const child of node.namedChildren) {\n if (child.type === 'dotted_name') {\n moduleName = child.text;\n break;\n }\n }\n }\n\n const fromPath = dots ? `${dots}${moduleName}` : moduleName;\n const isRelative = dots.length > 0;\n\n // Collect imported names\n const specifiers: string[] = [];\n for (const child of node.namedChildren) {\n if (child.type === 'dotted_name' && child !== moduleNode) {\n specifiers.push(child.text);\n } else if (child.type === 'aliased_import') {\n const nameNode = child.childForFieldName('name') ?? child.namedChildren[0];\n const aliasNode = child.childForFieldName('alias');\n if (nameNode) {\n specifiers.push(aliasNode?.text ?? nameNode.text);\n }\n }\n }\n\n // Handle wildcard import: `from foo import *`\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n if (child && child.type === 'wildcard_import') {\n specifiers.push('*');\n }\n }\n\n edges.push({\n edgeType: 'py_imports',\n metadata: {\n from: fromPath,\n specifiers,\n ...(isRelative ? { relative: true } : {}),\n },\n });\n }\n }\n\n return edges;\n}\n\n/** Get the name field from a node. */\nexport function getNodeName(node: TSNode): string | undefined {\n const nameNode = node.childForFieldName('name');\n return nameNode?.text;\n}\n\n/** Check if a name is ALL_CAPS (constant naming convention). */\nexport function isAllCaps(name: string): boolean {\n return /^[A-Z][A-Z0-9_]{2,}$/.test(name);\n}\n\n/** Extract base class names from the argument_list in a class_definition. */\nexport function extractClassBases(node: TSNode): string[] {\n const bases: string[] = [];\n const superclasses = node.childForFieldName('superclasses');\n if (!superclasses) return bases;\n\n for (const child of superclasses.namedChildren) {\n if (child.type === 'identifier' || child.type === 'attribute') {\n bases.push(child.text);\n } else if (child.type === 'call') {\n // e.g. metaclass=ABCMeta — skip keyword args\n const fn = child.childForFieldName('function');\n if (fn) bases.push(fn.text);\n } else if (child.type === 'keyword_argument') {\n // Skip keyword arguments like metaclass=...\n continue;\n }\n }\n\n return bases;\n}\n\n/** Extract methods from a class body node. */\nexport function extractClassMethods(\n body: TSNode,\n filePath: string,\n className: string,\n classSymbolId: string,\n): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n\n for (const child of body.namedChildren) {\n let funcNode: TSNode | null = null;\n let decorators: string[] = [];\n\n if (child.type === 'function_definition') {\n funcNode = child;\n } else if (child.type === 'decorated_definition') {\n decorators = extractDecorators(child);\n // Unwrap to get the actual function_definition\n funcNode = child.namedChildren.find(\n (c) => c.type === 'function_definition',\n ) ?? null;\n }\n\n if (!funcNode) continue;\n const name = getNodeName(funcNode);\n if (!name) continue;\n\n const isAsync = funcNode.namedChildren.some((c) => c.type === 'async');\n // Check if the function text starts with 'async'\n const asyncFlag = funcNode.text.trimStart().startsWith('async');\n\n const meta: Record<string, unknown> = {};\n if (asyncFlag || isAsync) meta.async = true;\n if (decorators.length > 0) meta.decorators = decorators;\n\n // Detect static/class methods via decorators\n if (decorators.includes('staticmethod')) meta.static = true;\n if (decorators.includes('classmethod')) meta.classmethod = true;\n if (decorators.includes('property')) meta.property = true;\n if (decorators.includes('abstractmethod')) meta.abstract = true;\n\n // Use the decorated_definition node for byte range if decorators present\n const rangeNode = child.type === 'decorated_definition' ? child : funcNode;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'method', className),\n name,\n kind: 'method',\n fqn: undefined, // set by the caller\n parentSymbolId: classSymbolId,\n signature: extractSignature(funcNode),\n byteStart: rangeNode.startIndex,\n byteEnd: rangeNode.endIndex,\n lineStart: rangeNode.startPosition.row + 1,\n lineEnd: rangeNode.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n }\n\n return symbols;\n}\n\n/**\n * Extract instance attributes from `__init__` method body.\n * Looks for `self.x = ...` patterns in the method body.\n */\nexport function extractInstanceAttributes(\n body: TSNode,\n filePath: string,\n className: string,\n classSymbolId: string,\n): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n const seen = new Set<string>();\n\n walkForSelfAssignments(body, filePath, className, classSymbolId, symbols, seen);\n\n return symbols;\n}\n\nfunction walkForSelfAssignments(\n node: TSNode,\n filePath: string,\n className: string,\n classSymbolId: string,\n symbols: RawSymbol[],\n seen: Set<string>,\n): void {\n for (const child of node.namedChildren) {\n if (child.type === 'expression_statement') {\n const expr = child.namedChildren[0];\n if (expr && expr.type === 'assignment') {\n const left = expr.childForFieldName('left');\n if (left && left.type === 'attribute') {\n const obj = left.childForFieldName('object');\n const attr = left.childForFieldName('attribute');\n if (obj && obj.text === 'self' && attr) {\n const name = attr.text;\n if (!seen.has(name)) {\n seen.add(name);\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'property', className),\n name,\n kind: 'property',\n parentSymbolId: classSymbolId,\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n });\n }\n }\n }\n }\n }\n // Recurse into if/elif/else/for/while/try/with blocks inside __init__\n if (\n child.type === 'if_statement' ||\n child.type === 'for_statement' ||\n child.type === 'while_statement' ||\n child.type === 'try_statement' ||\n child.type === 'with_statement' ||\n child.type === 'block'\n ) {\n walkForSelfAssignments(child, filePath, className, classSymbolId, symbols, seen);\n }\n }\n}\n","/**\n * Java Language Plugin — tree-sitter based symbol extraction.\n */\nimport { createRequire } from 'node:module';\nimport { ok, err } from 'neverthrow';\nimport type { LanguagePlugin, PluginManifest, FileParseResult, RawSymbol } from '../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../errors.js';\nimport { parseError } from '../../../errors.js';\nimport {\n type TSNode,\n makeSymbolId,\n makeFqn,\n extractPackageName,\n extractSignature,\n extractAnnotations,\n extractSuperTypes,\n extractInterfaceExtends,\n extractImportEdges,\n extractClassMethods,\n extractClassFields,\n extractEnumConstants,\n getNodeName,\n} from './java-helpers.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst JavaGrammar = require('tree-sitter-java');\n\nlet parserInstance: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(): InstanceType<typeof Parser> {\n if (!parserInstance) {\n parserInstance = new Parser();\n parserInstance!.setLanguage(JavaGrammar);\n }\n return parserInstance!;\n}\n\nexport class JavaLanguagePlugin implements LanguagePlugin {\n manifest: PluginManifest = {\n name: 'java-language',\n version: '1.0.0',\n priority: 5,\n };\n\n supportedExtensions = ['.java'];\n\n extractSymbols(filePath: string, content: Buffer): TraceMcpResult<FileParseResult> {\n try {\n const parser = getParser();\n const sourceCode = content.toString('utf-8');\n const tree = parser.parse(sourceCode);\n const root: TSNode = tree.rootNode;\n\n const hasError = root.hasError;\n const packageName = extractPackageName(root);\n const symbols: RawSymbol[] = [];\n const warnings: string[] = [];\n\n if (hasError) {\n warnings.push('Source contains syntax errors; extraction may be incomplete');\n }\n\n this.walkTopLevel(root, filePath, packageName, symbols);\n\n const edges = extractImportEdges(root);\n\n return ok({\n language: 'java',\n status: hasError ? 'partial' : 'ok',\n symbols,\n edges: edges.length > 0 ? edges : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return err(parseError(filePath, `Java parse failed: ${msg}`));\n }\n }\n\n private walkTopLevel(root: TSNode, filePath: string, packageName: string | undefined, symbols: RawSymbol[]): void {\n for (const child of root.namedChildren) {\n switch (child.type) {\n case 'class_declaration':\n this.extractClass(child, filePath, packageName, symbols);\n break;\n case 'interface_declaration':\n this.extractInterface(child, filePath, packageName, symbols);\n break;\n case 'enum_declaration':\n this.extractEnum(child, filePath, packageName, symbols);\n break;\n case 'annotation_type_declaration':\n this.extractAnnotationType(child, filePath, packageName, symbols);\n break;\n }\n }\n }\n\n private extractClass(node: TSNode, filePath: string, packageName: string | undefined, symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n\n const fqnParts = packageName ? [packageName, name] : [name];\n const symbolId = makeSymbolId(filePath, name, 'class');\n const annotations = extractAnnotations(node);\n const superTypes = extractSuperTypes(node);\n const meta: Record<string, unknown> = {};\n\n if (annotations.length > 0) meta.annotations = annotations;\n if (superTypes.extends_) meta.extends = superTypes.extends_;\n if (superTypes.implements_) meta.implements = superTypes.implements_;\n\n symbols.push({\n symbolId,\n name,\n kind: 'class',\n fqn: makeFqn(fqnParts),\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n\n const body = node.childForFieldName('body');\n if (body) {\n symbols.push(...extractClassMethods(body, filePath, name, symbolId));\n symbols.push(...extractClassFields(body, filePath, name, symbolId));\n // Nested classes\n for (const inner of body.namedChildren) {\n if (inner.type === 'class_declaration') {\n this.extractClass(inner, filePath, packageName, symbols);\n } else if (inner.type === 'interface_declaration') {\n this.extractInterface(inner, filePath, packageName, symbols);\n } else if (inner.type === 'enum_declaration') {\n this.extractEnum(inner, filePath, packageName, symbols);\n }\n }\n }\n }\n\n private extractInterface(node: TSNode, filePath: string, packageName: string | undefined, symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n\n const fqnParts = packageName ? [packageName, name] : [name];\n const symbolId = makeSymbolId(filePath, name, 'interface');\n const annotations = extractAnnotations(node);\n const extendsIfaces = extractInterfaceExtends(node);\n const meta: Record<string, unknown> = {};\n\n if (annotations.length > 0) meta.annotations = annotations;\n if (extendsIfaces.length > 0) meta.extends = extendsIfaces;\n\n symbols.push({\n symbolId,\n name,\n kind: 'interface',\n fqn: makeFqn(fqnParts),\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n\n const body = node.childForFieldName('body');\n if (body) {\n symbols.push(...extractClassMethods(body, filePath, name, symbolId));\n }\n }\n\n private extractEnum(node: TSNode, filePath: string, packageName: string | undefined, symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n\n const fqnParts = packageName ? [packageName, name] : [name];\n const symbolId = makeSymbolId(filePath, name, 'enum');\n\n symbols.push({\n symbolId,\n name,\n kind: 'enum',\n fqn: makeFqn(fqnParts),\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n });\n\n const body = node.childForFieldName('body');\n if (body) {\n symbols.push(...extractEnumConstants(body, filePath, name, symbolId));\n symbols.push(...extractClassMethods(body, filePath, name, symbolId));\n }\n }\n\n private extractAnnotationType(node: TSNode, filePath: string, packageName: string | undefined, symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n\n const fqnParts = packageName ? [packageName, name] : [name];\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'decorator'),\n name,\n kind: 'decorator',\n fqn: makeFqn(fqnParts),\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n });\n }\n}\n","/**\n * Helper utilities for the Java language plugin.\n * Extracts AST-walking logic to keep the main plugin concise.\n */\nimport type { RawSymbol, RawEdge, SymbolKind } from '../../../plugin-api/types.js';\n\n// tree-sitter types (CJS interop — no type package available)\ntype TSNode = {\n type: string;\n text: string;\n startIndex: number;\n endIndex: number;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n namedChildCount: number;\n childCount: number;\n namedChildren: TSNode[];\n namedChild(index: number): TSNode | null;\n child(index: number): TSNode | null;\n childForFieldName(name: string): TSNode | null;\n parent: TSNode | null;\n isNamed: boolean;\n hasError: boolean;\n};\n\nexport type { TSNode };\n\n/** Build a symbol ID following the convention: `path::Name#kind` */\nexport function makeSymbolId(\n relativePath: string,\n name: string,\n kind: SymbolKind,\n parentName?: string,\n): string {\n if (parentName) {\n return `${relativePath}::${parentName}::${name}#${kind}`;\n }\n return `${relativePath}::${name}#${kind}`;\n}\n\n/** Build a dotted fully-qualified name. */\nexport function makeFqn(parts: string[]): string {\n return parts.filter(Boolean).join('.');\n}\n\n/** Convert a file path to a Java-style dotted module path. */\nexport function filePathToModule(filePath: string): string {\n return filePath\n .replace(/\\\\/g, '/')\n .replace(/\\.java$/, '')\n .replace(/\\//g, '.');\n}\n\n/** Extract the package name from the root AST node. */\nexport function extractPackageName(root: TSNode): string | undefined {\n for (const child of root.namedChildren) {\n if (child.type === 'package_declaration') {\n // The package_declaration contains a scoped_identifier or identifier\n for (const inner of child.namedChildren) {\n if (inner.type === 'scoped_identifier' || inner.type === 'identifier') {\n return inner.text;\n }\n }\n }\n }\n return undefined;\n}\n\n/** Extract signature (first line of a node). */\nexport function extractSignature(node: TSNode): string {\n const firstLine = node.text.split('\\n')[0].trim();\n // Trim trailing opening brace\n const braceIdx = firstLine.indexOf('{');\n if (braceIdx > 0) {\n return firstLine.substring(0, braceIdx).trim();\n }\n return firstLine.replace(/;$/, '').trim();\n}\n\n/** Get the name of a node from its 'name' field or 'identifier' child. */\nexport function getNodeName(node: TSNode): string | undefined {\n const nameNode = node.childForFieldName('name');\n if (nameNode) return nameNode.text;\n // Fallback: look for identifier child\n for (const child of node.namedChildren) {\n if (child.type === 'identifier') return child.text;\n }\n return undefined;\n}\n\n/** Extract annotation names from a modifiers node. */\nexport function extractAnnotations(node: TSNode): string[] {\n const annotations: string[] = [];\n const modifiers = node.childForFieldName('modifiers') ?? findChildByType(node, 'modifiers');\n if (!modifiers) return annotations;\n\n for (const child of modifiers.namedChildren) {\n if (child.type === 'marker_annotation' || child.type === 'annotation') {\n const nameNode = child.childForFieldName('name') ?? findChildByType(child, 'identifier') ?? findChildByType(child, 'scoped_identifier');\n if (nameNode) {\n annotations.push(nameNode.text);\n }\n }\n }\n return annotations;\n}\n\n/** Extract modifier keywords (public, static, final, abstract, etc.) from a modifiers node. */\nexport function extractModifierKeywords(node: TSNode): string[] {\n const keywords: string[] = [];\n const modifiers = node.childForFieldName('modifiers') ?? findChildByType(node, 'modifiers');\n if (!modifiers) return keywords;\n\n for (let i = 0; i < modifiers.childCount; i++) {\n const child = modifiers.child(i);\n if (!child) continue;\n if (!child.isNamed && ['public', 'private', 'protected', 'static', 'final', 'abstract', 'default', 'synchronized', 'native', 'transient', 'volatile'].includes(child.text)) {\n keywords.push(child.text);\n }\n }\n return keywords;\n}\n\n/** Find extends/implements clauses on a class_declaration. */\nexport function extractSuperTypes(node: TSNode): { extends_?: string; implements_?: string[] } {\n const result: { extends_?: string; implements_?: string[] } = {};\n\n const superclass = node.childForFieldName('superclass');\n if (superclass) {\n // superclass node may be a type_identifier itself, or a wrapper containing one\n const typeNode = superclass.type === 'type_identifier' || superclass.type === 'generic_type' || superclass.type === 'scoped_type_identifier'\n ? superclass\n : superclass.namedChildren.find((c) => c.type === 'type_identifier' || c.type === 'generic_type' || c.type === 'scoped_type_identifier');\n result.extends_ = typeNode ? typeNode.text : superclass.text.replace(/^extends\\s+/, '').trim();\n }\n\n const interfaces = node.childForFieldName('interfaces');\n if (interfaces) {\n // super_interfaces / interface_type_list\n const types: string[] = [];\n for (const child of interfaces.namedChildren) {\n if (child.type === 'type_list') {\n for (const t of child.namedChildren) {\n types.push(t.text);\n }\n } else {\n types.push(child.text);\n }\n }\n if (types.length > 0) result.implements_ = types;\n }\n\n return result;\n}\n\n/** Find extends clauses on an interface_declaration. */\nexport function extractInterfaceExtends(node: TSNode): string[] {\n const result: string[] = [];\n const extendsNode = node.childForFieldName('extends');\n if (extendsNode) {\n // extends_interfaces / interface_type_list\n for (const child of extendsNode.namedChildren) {\n if (child.type === 'type_list') {\n for (const t of child.namedChildren) {\n result.push(t.text);\n }\n } else {\n result.push(child.text);\n }\n }\n }\n return result;\n}\n\n/** Extract import edges from the root program node. */\nexport function extractImportEdges(root: TSNode): RawEdge[] {\n const edges: RawEdge[] = [];\n\n for (const node of root.namedChildren) {\n if (node.type === 'import_declaration') {\n // import_declaration contains a scoped_identifier and optionally asterisk\n let importPath = '';\n let isWildcard = false;\n\n for (const child of node.namedChildren) {\n if (child.type === 'scoped_identifier' || child.type === 'identifier') {\n importPath = child.text;\n }\n if (child.type === 'asterisk') {\n isWildcard = true;\n }\n }\n\n // Check for static import\n let isStatic = false;\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n if (child && child.text === 'static') {\n isStatic = true;\n break;\n }\n }\n\n if (importPath) {\n const fullPath = isWildcard ? `${importPath}.*` : importPath;\n const lastDot = importPath.lastIndexOf('.');\n const simpleName = lastDot >= 0 ? importPath.substring(lastDot + 1) : importPath;\n\n edges.push({\n edgeType: 'imports',\n metadata: {\n from: fullPath,\n specifiers: isWildcard ? ['*'] : [simpleName],\n ...(isStatic ? { static: true } : {}),\n },\n });\n }\n }\n }\n\n return edges;\n}\n\n/** Extract methods from a class body. */\nexport function extractClassMethods(\n body: TSNode,\n filePath: string,\n className: string,\n classSymbolId: string,\n): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n\n for (const child of body.namedChildren) {\n if (child.type === 'method_declaration') {\n const name = getNodeName(child);\n if (!name) continue;\n\n const annotations = extractAnnotations(child);\n const modifiers = extractModifierKeywords(child);\n const meta: Record<string, unknown> = {};\n\n if (annotations.length > 0) meta.annotations = annotations;\n if (modifiers.includes('static')) meta.static = true;\n if (modifiers.includes('abstract')) meta.abstract = true;\n if (modifiers.includes('final')) meta.final = true;\n if (annotations.includes('Override')) meta.override = true;\n\n const visibility = modifiers.find((m) => ['public', 'private', 'protected'].includes(m));\n if (visibility) meta.visibility = visibility;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'method', className),\n name,\n kind: 'method',\n parentSymbolId: classSymbolId,\n signature: extractSignature(child),\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n } else if (child.type === 'constructor_declaration') {\n const name = getNodeName(child) ?? className;\n const annotations = extractAnnotations(child);\n const modifiers = extractModifierKeywords(child);\n const meta: Record<string, unknown> = {};\n\n if (annotations.length > 0) meta.annotations = annotations;\n meta.isConstructor = true;\n const visibility = modifiers.find((m) => ['public', 'private', 'protected'].includes(m));\n if (visibility) meta.visibility = visibility;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'method', className),\n name,\n kind: 'method',\n parentSymbolId: classSymbolId,\n signature: extractSignature(child),\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n }\n }\n\n return symbols;\n}\n\n/** Extract fields from a class body. */\nexport function extractClassFields(\n body: TSNode,\n filePath: string,\n className: string,\n classSymbolId: string,\n): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n\n for (const child of body.namedChildren) {\n if (child.type === 'field_declaration') {\n const annotations = extractAnnotations(child);\n const modifiers = extractModifierKeywords(child);\n\n // A field_declaration can have multiple variable_declarators\n for (const vc of child.namedChildren) {\n if (vc.type === 'variable_declarator') {\n const name = getNodeName(vc);\n if (!name) continue;\n\n const isConstant = modifiers.includes('static') && modifiers.includes('final');\n const kind: SymbolKind = isConstant ? 'constant' : 'property';\n\n const meta: Record<string, unknown> = {};\n if (annotations.length > 0) meta.annotations = annotations;\n if (modifiers.includes('static')) meta.static = true;\n if (modifiers.includes('final')) meta.final = true;\n const visibility = modifiers.find((m) => ['public', 'private', 'protected'].includes(m));\n if (visibility) meta.visibility = visibility;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, kind, className),\n name,\n kind,\n parentSymbolId: classSymbolId,\n signature: child.text.split('\\n')[0].trim().replace(/;$/, ''),\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n }\n }\n }\n }\n\n return symbols;\n}\n\n/** Extract enum constants from an enum body. */\nexport function extractEnumConstants(\n body: TSNode,\n filePath: string,\n enumName: string,\n enumSymbolId: string,\n): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n\n for (const child of body.namedChildren) {\n if (child.type === 'enum_constant') {\n const name = getNodeName(child);\n if (!name) continue;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'enum_case', enumName),\n name,\n kind: 'enum_case',\n parentSymbolId: enumSymbolId,\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n });\n }\n }\n\n return symbols;\n}\n\n/** Check if a name is ALL_CAPS (constant naming convention). */\nexport function isAllCaps(name: string): boolean {\n return /^[A-Z][A-Z0-9_]{2,}$/.test(name);\n}\n\n/** Find the first child of a given type. */\nfunction findChildByType(node: TSNode, type: string): TSNode | undefined {\n for (const child of node.namedChildren) {\n if (child.type === type) return child;\n }\n return undefined;\n}\n","/**\n * Kotlin Language Plugin — regex-based symbol extraction.\n * Uses regex rather than tree-sitter-kotlin for reliability.\n */\nimport { ok, err } from 'neverthrow';\nimport type { LanguagePlugin, PluginManifest, FileParseResult, RawSymbol, RawEdge, SymbolKind } from '../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../errors.js';\nimport { parseError } from '../../../errors.js';\n\nexport class KotlinLanguagePlugin implements LanguagePlugin {\n manifest: PluginManifest = {\n name: 'kotlin-language',\n version: '1.0.0',\n priority: 5,\n };\n\n supportedExtensions = ['.kt', '.kts'];\n\n extractSymbols(filePath: string, content: Buffer): TraceMcpResult<FileParseResult> {\n try {\n const source = content.toString('utf-8');\n const lines = source.split('\\n');\n const symbols: RawSymbol[] = [];\n const edges: RawEdge[] = [];\n\n // Package\n const pkgMatch = source.match(/^package\\s+([\\w.]+)/m);\n const packageName = pkgMatch?.[1];\n\n // Imports\n const importRe = /^import\\s+([\\w.]+)(?:\\s+as\\s+(\\w+))?/gm;\n let im: RegExpExecArray | null;\n while ((im = importRe.exec(source)) !== null) {\n const parts = im[1].split('.');\n edges.push({\n edgeType: 'imports',\n metadata: {\n from: im[1],\n specifiers: [im[2] ?? parts[parts.length - 1]],\n },\n });\n }\n\n // Classes, interfaces, objects, enums\n const classRe = /^(\\s*)(?:(@\\w+(?:\\([^)]*\\))?)\\s+)*(?:(abstract|sealed|data|open|inner|enum|annotation)\\s+)*(?:(class|interface|object))\\s+(\\w+)(?:\\s*(?:<[^>]+>)?)?(?:\\s*\\(([^)]*)\\))?(?:\\s*:\\s*([^\\{]+))?(?:\\s*\\{)?/gm;\n let cm: RegExpExecArray | null;\n while ((cm = classRe.exec(source)) !== null) {\n const modifiers = cm[3] ?? '';\n const keyword = cm[4];\n const name = cm[5];\n const heritage = cm[7]?.trim();\n const lineNum = source.substring(0, cm.index).split('\\n').length;\n const byteStart = cm.index;\n\n let kind: SymbolKind = 'class';\n if (keyword === 'interface') kind = 'interface';\n else if (keyword === 'object') kind = 'class';\n\n if (modifiers === 'enum') kind = 'enum';\n\n const meta: Record<string, unknown> = {};\n if (modifiers) meta.modifiers = modifiers;\n if (keyword === 'object') meta.object = true;\n if (modifiers === 'data') meta.data = true;\n\n if (heritage) {\n const parents = heritage.split(',').map((s) => s.trim().replace(/\\(.*\\)$/, '').trim());\n if (parents.length > 0) {\n // First is typically extends, rest are implements\n meta.extends = parents[0];\n if (parents.length > 1) meta.implements = parents.slice(1);\n }\n }\n\n const fqnParts = packageName ? [packageName, name] : [name];\n\n symbols.push({\n symbolId: `${filePath}::${name}#${kind}`,\n name,\n kind,\n fqn: fqnParts.join('.'),\n signature: cm[0].trim().replace(/\\{$/, '').trim(),\n byteStart,\n byteEnd: byteStart + cm[0].length,\n lineStart: lineNum,\n lineEnd: lineNum,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n }\n\n // Functions (top-level and member)\n const funRe = /^(\\s*)(?:(?:override|suspend|inline|private|public|protected|internal|open|abstract)\\s+)*fun\\s+(?:<[^>]+>\\s+)?(\\w+)\\s*\\(([^)]*)\\)(?:\\s*:\\s*([^\\{=]+?))?/gm;\n let fm: RegExpExecArray | null;\n while ((fm = funRe.exec(source)) !== null) {\n const indent = fm[1].length;\n const name = fm[2];\n const lineNum = source.substring(0, fm.index).split('\\n').length;\n\n const kind: SymbolKind = indent > 0 ? 'method' : 'function';\n const fqnParts = packageName ? [packageName, name] : [name];\n\n symbols.push({\n symbolId: `${filePath}::${name}#${kind}`,\n name,\n kind,\n fqn: fqnParts.join('.'),\n signature: fm[0].trim(),\n byteStart: fm.index,\n byteEnd: fm.index + fm[0].length,\n lineStart: lineNum,\n lineEnd: lineNum,\n });\n }\n\n // Properties (val/var at class level)\n const propRe = /^\\s+(?:(?:override|private|public|protected|internal|lateinit|lazy|const)\\s+)*(?:val|var)\\s+(\\w+)(?:\\s*:\\s*(\\S+))?/gm;\n let pm: RegExpExecArray | null;\n while ((pm = propRe.exec(source)) !== null) {\n const name = pm[1];\n const lineNum = source.substring(0, pm.index).split('\\n').length;\n\n symbols.push({\n symbolId: `${filePath}::${name}#property`,\n name,\n kind: 'property',\n signature: pm[0].trim(),\n byteStart: pm.index,\n byteEnd: pm.index + pm[0].length,\n lineStart: lineNum,\n lineEnd: lineNum,\n metadata: pm[2] ? { type: pm[2] } : undefined,\n });\n }\n\n // Top-level const val\n const constRe = /^(?:const\\s+)?val\\s+([A-Z][A-Z0-9_]+)\\s*(?::\\s*\\S+)?\\s*=/gm;\n let cc: RegExpExecArray | null;\n while ((cc = constRe.exec(source)) !== null) {\n const name = cc[1];\n const lineNum = source.substring(0, cc.index).split('\\n').length;\n\n symbols.push({\n symbolId: `${filePath}::${name}#constant`,\n name,\n kind: 'constant',\n fqn: packageName ? `${packageName}.${name}` : name,\n signature: cc[0].trim(),\n byteStart: cc.index,\n byteEnd: cc.index + cc[0].length,\n lineStart: lineNum,\n lineEnd: lineNum,\n });\n }\n\n return ok({\n language: 'kotlin',\n status: 'ok',\n symbols,\n edges: edges.length > 0 ? edges : undefined,\n });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return err(parseError(filePath, `Kotlin parse failed: ${msg}`));\n }\n }\n}\n","/**\n * Ruby Language Plugin — tree-sitter based symbol extraction.\n */\nimport { createRequire } from 'node:module';\nimport { ok, err } from 'neverthrow';\nimport type { LanguagePlugin, PluginManifest, FileParseResult, RawSymbol } from '../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../errors.js';\nimport { parseError } from '../../../errors.js';\nimport {\n type TSNode,\n makeSymbolId,\n makeFqn,\n extractSignature,\n extractSuperclass,\n extractMethods,\n extractAttributes,\n extractMixins,\n extractImportEdges,\n extractConstants,\n getNodeName,\n} from './ruby-helpers.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst RubyGrammar = require('tree-sitter-ruby');\n\nlet parserInstance: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(): InstanceType<typeof Parser> {\n if (!parserInstance) {\n parserInstance = new Parser();\n parserInstance!.setLanguage(RubyGrammar);\n }\n return parserInstance!;\n}\n\nexport class RubyLanguagePlugin implements LanguagePlugin {\n manifest: PluginManifest = {\n name: 'ruby-language',\n version: '1.0.0',\n priority: 5,\n };\n\n supportedExtensions = ['.rb', '.rake'];\n\n extractSymbols(filePath: string, content: Buffer): TraceMcpResult<FileParseResult> {\n try {\n const parser = getParser();\n const sourceCode = content.toString('utf-8');\n const tree = parser.parse(sourceCode);\n const root: TSNode = tree.rootNode;\n\n const hasError = root.hasError;\n const symbols: RawSymbol[] = [];\n const warnings: string[] = [];\n\n if (hasError) {\n warnings.push('Source contains syntax errors; extraction may be incomplete');\n }\n\n this.walkNode(root, filePath, [], symbols);\n\n const edges = extractImportEdges(root);\n\n return ok({\n language: 'ruby',\n status: hasError ? 'partial' : 'ok',\n symbols,\n edges: edges.length > 0 ? edges : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return err(parseError(filePath, `Ruby parse failed: ${msg}`));\n }\n }\n\n private walkNode(node: TSNode, filePath: string, namespaceParts: string[], symbols: RawSymbol[]): void {\n for (const child of node.namedChildren) {\n switch (child.type) {\n case 'class':\n this.extractClass(child, filePath, namespaceParts, symbols);\n break;\n case 'module':\n this.extractModule(child, filePath, namespaceParts, symbols);\n break;\n case 'method':\n this.extractTopLevelMethod(child, filePath, namespaceParts, symbols);\n break;\n case 'assignment':\n this.extractTopLevelConstant(child, filePath, namespaceParts, symbols);\n break;\n }\n }\n }\n\n private extractClass(node: TSNode, filePath: string, namespaceParts: string[], symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n\n const parts = [...namespaceParts, name];\n const symbolId = makeSymbolId(filePath, name, 'class', namespaceParts.length > 0 ? namespaceParts.join('::') : undefined);\n const superclass = extractSuperclass(node);\n const meta: Record<string, unknown> = {};\n\n if (superclass) meta.extends = superclass;\n\n const body = node.childForFieldName('body') ?? node;\n\n const mixins = extractMixins(body);\n if (mixins.include) meta.includes = mixins.include;\n if (mixins.extend) meta.extends_modules = mixins.extend;\n if (mixins.prepend) meta.prepends = mixins.prepend;\n\n symbols.push({\n symbolId,\n name,\n kind: 'class',\n fqn: makeFqn(parts),\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n\n symbols.push(...extractMethods(body, filePath, name, symbolId, parts));\n symbols.push(...extractAttributes(body, filePath, name, symbolId, parts));\n symbols.push(...extractConstants(body, filePath, name, symbolId, parts));\n\n // Nested classes/modules\n this.walkNode(body, filePath, parts, symbols);\n }\n\n private extractModule(node: TSNode, filePath: string, namespaceParts: string[], symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n\n const parts = [...namespaceParts, name];\n const symbolId = makeSymbolId(filePath, name, 'namespace', namespaceParts.length > 0 ? namespaceParts.join('::') : undefined);\n\n const body = node.childForFieldName('body') ?? node;\n\n const mixins = extractMixins(body);\n const meta: Record<string, unknown> = {};\n if (mixins.include) meta.includes = mixins.include;\n if (mixins.extend) meta.extends_modules = mixins.extend;\n\n symbols.push({\n symbolId,\n name,\n kind: 'namespace',\n fqn: makeFqn(parts),\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n\n symbols.push(...extractMethods(body, filePath, name, symbolId, parts));\n symbols.push(...extractAttributes(body, filePath, name, symbolId, parts));\n symbols.push(...extractConstants(body, filePath, name, symbolId, parts));\n\n // Nested classes/modules\n this.walkNode(body, filePath, parts, symbols);\n }\n\n private extractTopLevelMethod(node: TSNode, filePath: string, namespaceParts: string[], symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'function'),\n name,\n kind: 'function',\n fqn: namespaceParts.length > 0 ? makeFqn(namespaceParts, name) : name,\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n });\n }\n\n private extractTopLevelConstant(node: TSNode, filePath: string, namespaceParts: string[], symbols: RawSymbol[]): void {\n const left = node.childForFieldName('left');\n if (!left || left.type !== 'constant') return;\n const name = left.text;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'constant'),\n name,\n kind: 'constant',\n fqn: namespaceParts.length > 0 ? makeFqn([...namespaceParts, name]) : name,\n signature: node.text.split('\\n')[0].trim().slice(0, 120),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n });\n }\n}\n","/**\n * Helper utilities for the Ruby language plugin.\n * Extracts AST-walking logic to keep the main plugin manageable.\n */\nimport type { RawSymbol, RawEdge, SymbolKind } from '../../../plugin-api/types.js';\n\n// tree-sitter types (CJS interop — no type package available)\ntype TSNode = {\n type: string;\n text: string;\n startIndex: number;\n endIndex: number;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n namedChildCount: number;\n childCount: number;\n namedChildren: TSNode[];\n namedChild(index: number): TSNode | null;\n child(index: number): TSNode | null;\n childForFieldName(name: string): TSNode | null;\n parent: TSNode | null;\n isNamed: boolean;\n hasError: boolean;\n};\n\nexport type { TSNode };\n\n/** Build a symbol ID following the convention: `path::Name#kind` */\nexport function makeSymbolId(\n relativePath: string,\n name: string,\n kind: SymbolKind,\n parentName?: string,\n): string {\n if (parentName) {\n return `${relativePath}::${parentName}::${name}#${kind}`;\n }\n return `${relativePath}::${name}#${kind}`;\n}\n\n/**\n * Build a `::` separated fully-qualified name for a Ruby symbol.\n * Module/class parts use `::`, methods use `.`.\n */\nexport function makeFqn(namespaceParts: string[], methodName?: string): string {\n const base = namespaceParts.join('::');\n if (methodName) {\n return `${base}.${methodName}`;\n }\n return base;\n}\n\n/** Convert a file path to a Ruby module-style path (for FQN prefix). */\nexport function filePathToModule(filePath: string): string {\n return filePath\n .replace(/\\\\/g, '/')\n .replace(/\\.(rb|rake)$/, '');\n}\n\n/** Extract signature — first line of the node text. */\nexport function extractSignature(node: TSNode): string {\n const firstLine = node.text.split('\\n')[0].trim();\n return firstLine;\n}\n\n/** Get the name field from a node. */\nexport function getNodeName(node: TSNode): string | undefined {\n const nameNode = node.childForFieldName('name');\n return nameNode?.text;\n}\n\n/** Check if a name is ALL_CAPS (constant naming convention). */\nexport function isAllCaps(name: string): boolean {\n return /^[A-Z][A-Z0-9_]{2,}$/.test(name);\n}\n\n/** Extract the superclass from a class definition. */\nexport function extractSuperclass(node: TSNode): string | undefined {\n const superNode = node.childForFieldName('superclass');\n if (superNode) {\n // tree-sitter may include the `< ` prefix in the text\n return superNode.text.replace(/^<\\s*/, '').trim();\n }\n return undefined;\n}\n\n/** Extract methods from a class/module body node. */\nexport function extractMethods(\n body: TSNode,\n filePath: string,\n containerName: string,\n containerSymbolId: string,\n namespaceParts: string[],\n): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n\n for (const child of body.namedChildren) {\n if (child.type === 'method') {\n const name = getNodeName(child);\n if (!name) continue;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'method', containerName),\n name,\n kind: 'method',\n fqn: makeFqn(namespaceParts, name),\n parentSymbolId: containerSymbolId,\n signature: extractSignature(child),\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n });\n } else if (child.type === 'singleton_method') {\n // def self.method_name\n const nameNode = child.childForFieldName('name');\n if (!nameNode) continue;\n const name = nameNode.text;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, `self.${name}`, 'method', containerName),\n name: `self.${name}`,\n kind: 'method',\n fqn: makeFqn(namespaceParts, `self.${name}`),\n parentSymbolId: containerSymbolId,\n signature: extractSignature(child),\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n metadata: { static: true },\n });\n }\n }\n\n return symbols;\n}\n\n/** Extract attr_accessor/attr_reader/attr_writer properties from a class/module body. */\nexport function extractAttributes(\n body: TSNode,\n filePath: string,\n containerName: string,\n containerSymbolId: string,\n namespaceParts: string[],\n): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n\n for (const child of body.namedChildren) {\n if (child.type !== 'call') continue;\n\n const methodNode = child.childForFieldName('method');\n if (!methodNode) continue;\n const methodName = methodNode.text;\n\n if (methodName !== 'attr_accessor' && methodName !== 'attr_reader' && methodName !== 'attr_writer') {\n continue;\n }\n\n const args = child.childForFieldName('arguments');\n if (!args) continue;\n\n for (const arg of args.namedChildren) {\n let attrName: string | undefined;\n if (arg.type === 'simple_symbol') {\n // :name → strip the leading colon\n attrName = arg.text.replace(/^:/, '');\n } else if (arg.type === 'symbol') {\n attrName = arg.text.replace(/^:/, '');\n }\n if (!attrName) continue;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, attrName, 'property', containerName),\n name: attrName,\n kind: 'property',\n fqn: makeFqn(namespaceParts, attrName),\n parentSymbolId: containerSymbolId,\n byteStart: arg.startIndex,\n byteEnd: arg.endIndex,\n lineStart: arg.startPosition.row + 1,\n lineEnd: arg.endPosition.row + 1,\n metadata: { accessor: methodName },\n });\n }\n }\n\n return symbols;\n}\n\n/**\n * Extract include/extend/prepend mixins from a class/module body.\n * Returns an array of module names.\n */\nexport function extractMixins(body: TSNode): Record<string, string[]> {\n const mixins: Record<string, string[]> = {};\n\n for (const child of body.namedChildren) {\n if (child.type !== 'call') continue;\n\n const methodNode = child.childForFieldName('method');\n if (!methodNode) continue;\n const methodName = methodNode.text;\n\n if (methodName !== 'include' && methodName !== 'extend' && methodName !== 'prepend') {\n continue;\n }\n\n const args = child.childForFieldName('arguments');\n if (!args) continue;\n\n for (const arg of args.namedChildren) {\n if (arg.type === 'constant' || arg.type === 'scope_resolution') {\n if (!mixins[methodName]) mixins[methodName] = [];\n mixins[methodName].push(arg.text);\n }\n }\n }\n\n return mixins;\n}\n\n/**\n * Extract import edges from require/require_relative statements.\n *\n * Patterns:\n * - `require 'path'` → { edgeType: 'imports', metadata: { from: 'path' } }\n * - `require_relative 'path'` → { edgeType: 'imports', metadata: { from: 'path', relative: true } }\n */\nexport function extractImportEdges(root: TSNode): RawEdge[] {\n const edges: RawEdge[] = [];\n\n walkForImports(root, edges);\n\n return edges;\n}\n\nfunction walkForImports(node: TSNode, edges: RawEdge[]): void {\n if (node.type === 'call') {\n const methodNode = node.childForFieldName('method');\n if (methodNode) {\n const methodName = methodNode.text;\n if (methodName === 'require' || methodName === 'require_relative') {\n const args = node.childForFieldName('arguments');\n if (args) {\n for (const arg of args.namedChildren) {\n if (arg.type === 'string') {\n const content = extractStringContent(arg);\n if (content) {\n edges.push({\n edgeType: 'imports',\n metadata: {\n from: content,\n ...(methodName === 'require_relative' ? { relative: true } : {}),\n },\n });\n }\n }\n }\n }\n }\n }\n }\n\n for (const child of node.namedChildren) {\n walkForImports(child, edges);\n }\n}\n\n/** Extract string content, stripping quotes. */\nfunction extractStringContent(node: TSNode): string | null {\n // string node children: string_beginning + string_content + string_end\n // OR it's a simple string whose text has quotes\n for (const child of node.namedChildren) {\n if (child.type === 'string_content') {\n return child.text;\n }\n }\n // Fallback: strip outer quotes from the text\n const text = node.text;\n if ((text.startsWith('\"') && text.endsWith('\"')) || (text.startsWith(\"'\") && text.endsWith(\"'\"))) {\n return text.slice(1, -1);\n }\n return null;\n}\n\n/** Extract UPPER_CASE constant assignments from a body. */\nexport function extractConstants(\n body: TSNode,\n filePath: string,\n containerName: string | undefined,\n containerSymbolId: string | undefined,\n namespaceParts: string[],\n): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n\n for (const child of body.namedChildren) {\n if (child.type === 'assignment') {\n const left = child.childForFieldName('left');\n if (left && left.type === 'constant') {\n const name = left.text;\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'constant', containerName),\n name,\n kind: 'constant',\n fqn: makeFqn([...namespaceParts, name]),\n parentSymbolId: containerSymbolId,\n signature: child.text.split('\\n')[0].trim().slice(0, 120),\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n });\n }\n }\n }\n\n return symbols;\n}\n","/**\n * Go Language Plugin — tree-sitter based symbol extraction.\n */\nimport { createRequire } from 'node:module';\nimport { ok, err } from 'neverthrow';\nimport type { LanguagePlugin, PluginManifest, FileParseResult, RawSymbol } from '../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../errors.js';\nimport { parseError } from '../../../errors.js';\nimport {\n type TSNode,\n makeSymbolId,\n makeFqn,\n extractPackageName,\n extractSignature,\n extractImportEdges,\n extractStructFields,\n extractInterfaceMethods,\n getNodeName,\n} from './go-helpers.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst GoGrammar = require('tree-sitter-go');\n\nlet parserInstance: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(): InstanceType<typeof Parser> {\n if (!parserInstance) {\n parserInstance = new Parser();\n parserInstance!.setLanguage(GoGrammar);\n }\n return parserInstance!;\n}\n\nexport class GoLanguagePlugin implements LanguagePlugin {\n manifest: PluginManifest = {\n name: 'go-language',\n version: '1.0.0',\n priority: 5,\n };\n\n supportedExtensions = ['.go'];\n\n extractSymbols(filePath: string, content: Buffer): TraceMcpResult<FileParseResult> {\n try {\n const parser = getParser();\n const sourceCode = content.toString('utf-8');\n const tree = parser.parse(sourceCode);\n const root: TSNode = tree.rootNode;\n\n const hasError = root.hasError;\n const packageName = extractPackageName(root) ?? '';\n const symbols: RawSymbol[] = [];\n const warnings: string[] = [];\n\n if (hasError) {\n warnings.push('Source contains syntax errors; extraction may be incomplete');\n }\n\n for (const child of root.namedChildren) {\n switch (child.type) {\n case 'function_declaration':\n this.extractFunction(child, filePath, packageName, symbols);\n break;\n case 'method_declaration':\n this.extractMethod(child, filePath, packageName, symbols);\n break;\n case 'type_declaration':\n this.extractTypeDecl(child, filePath, packageName, symbols);\n break;\n case 'const_declaration':\n this.extractConsts(child, filePath, packageName, symbols);\n break;\n case 'var_declaration':\n this.extractVars(child, filePath, packageName, symbols);\n break;\n }\n }\n\n const edges = extractImportEdges(root);\n\n return ok({\n language: 'go',\n status: hasError ? 'partial' : 'ok',\n symbols,\n edges: edges.length > 0 ? edges : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return err(parseError(filePath, `Go parse failed: ${msg}`));\n }\n }\n\n private extractFunction(node: TSNode, filePath: string, pkg: string, symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n\n const meta: Record<string, unknown> = {};\n if (name[0] === name[0].toUpperCase()) meta.exported = 1;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'function'),\n name,\n kind: 'function',\n fqn: makeFqn([pkg, name]),\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n }\n\n private extractMethod(node: TSNode, filePath: string, pkg: string, symbols: RawSymbol[]): void {\n const name = getNodeName(node);\n if (!name) return;\n\n const receiver = node.childForFieldName('receiver');\n let receiverType = '';\n if (receiver) {\n // parameter_list → parameter_declaration → type\n for (const param of receiver.namedChildren) {\n if (param.type === 'parameter_declaration') {\n const typeNode = param.childForFieldName('type');\n if (typeNode) receiverType = typeNode.text.replace(/^\\*/, '');\n }\n }\n }\n\n const parentSymbolId = receiverType ? makeSymbolId(filePath, receiverType, 'class') : undefined;\n const meta: Record<string, unknown> = {};\n if (name[0] === name[0].toUpperCase()) meta.exported = 1;\n if (receiver) meta.receiver = receiver.text.replace(/^\\(|\\)$/g, '');\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'method', receiverType || undefined),\n name,\n kind: 'method',\n fqn: receiverType ? makeFqn([pkg, receiverType, name]) : makeFqn([pkg, name]),\n parentSymbolId,\n signature: extractSignature(node),\n byteStart: node.startIndex,\n byteEnd: node.endIndex,\n lineStart: node.startPosition.row + 1,\n lineEnd: node.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n }\n\n private extractTypeDecl(node: TSNode, filePath: string, pkg: string, symbols: RawSymbol[]): void {\n for (const spec of node.namedChildren) {\n if (spec.type === 'type_spec') {\n const name = getNodeName(spec);\n if (!name) continue;\n\n const typeNode = spec.childForFieldName('type');\n if (!typeNode) continue;\n\n const meta: Record<string, unknown> = {};\n if (name[0] === name[0].toUpperCase()) meta.exported = 1;\n\n if (typeNode.type === 'struct_type') {\n const symbolId = makeSymbolId(filePath, name, 'class');\n const body = typeNode.childForFieldName('body') ?? typeNode.namedChildren.find((c) => c.type === 'field_declaration_list');\n\n let fieldSymbols: RawSymbol[] = [];\n if (body) {\n const result = extractStructFields(body, filePath, name, symbolId);\n fieldSymbols = result.symbols;\n if (result.embeds.length > 0) meta.embeds = result.embeds;\n }\n\n symbols.push({\n symbolId,\n name,\n kind: 'class',\n fqn: makeFqn([pkg, name]),\n signature: `type ${name} struct`,\n byteStart: spec.startIndex,\n byteEnd: spec.endIndex,\n lineStart: spec.startPosition.row + 1,\n lineEnd: spec.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n symbols.push(...fieldSymbols);\n } else if (typeNode.type === 'interface_type') {\n const symbolId = makeSymbolId(filePath, name, 'interface');\n const body = typeNode.namedChildren.find((c) => c.type === 'method_spec' || c.type === 'method_elem')\n ? typeNode\n : typeNode.namedChildren[0]?.type === 'method_spec' ? typeNode : null;\n\n // Interface methods live directly inside interface_type\n let methodSymbols: RawSymbol[] = [];\n if (typeNode) {\n methodSymbols = extractInterfaceMethods(typeNode, filePath, name, symbolId);\n }\n\n symbols.push({\n symbolId,\n name,\n kind: 'interface',\n fqn: makeFqn([pkg, name]),\n signature: `type ${name} interface`,\n byteStart: spec.startIndex,\n byteEnd: spec.endIndex,\n lineStart: spec.startPosition.row + 1,\n lineEnd: spec.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n symbols.push(...methodSymbols);\n } else {\n // Type alias or other type definition\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'type'),\n name,\n kind: 'type',\n fqn: makeFqn([pkg, name]),\n signature: `type ${name} ${typeNode.text.split('\\n')[0]}`,\n byteStart: spec.startIndex,\n byteEnd: spec.endIndex,\n lineStart: spec.startPosition.row + 1,\n lineEnd: spec.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n }\n }\n }\n }\n\n private extractConsts(node: TSNode, filePath: string, pkg: string, symbols: RawSymbol[]): void {\n for (const child of node.namedChildren) {\n if (child.type === 'const_spec') {\n const name = getNodeName(child);\n if (!name) continue;\n\n const meta: Record<string, unknown> = {};\n if (name[0] === name[0].toUpperCase()) meta.exported = 1;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'constant'),\n name,\n kind: 'constant',\n fqn: makeFqn([pkg, name]),\n signature: child.text.split('\\n')[0].trim(),\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n }\n }\n }\n\n private extractVars(node: TSNode, filePath: string, pkg: string, symbols: RawSymbol[]): void {\n for (const child of node.namedChildren) {\n if (child.type === 'var_spec') {\n const name = getNodeName(child);\n if (!name) continue;\n\n const meta: Record<string, unknown> = {};\n if (name[0] === name[0].toUpperCase()) meta.exported = 1;\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'variable'),\n name,\n kind: 'variable',\n fqn: makeFqn([pkg, name]),\n signature: child.text.split('\\n')[0].trim(),\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n }\n }\n }\n}\n","/**\n * Helper utilities for the Go language plugin.\n */\nimport type { RawSymbol, RawEdge, SymbolKind } from '../../../plugin-api/types.js';\n\ntype TSNode = {\n type: string;\n text: string;\n startIndex: number;\n endIndex: number;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n namedChildCount: number;\n childCount: number;\n namedChildren: TSNode[];\n namedChild(index: number): TSNode | null;\n child(index: number): TSNode | null;\n childForFieldName(name: string): TSNode | null;\n parent: TSNode | null;\n isNamed: boolean;\n hasError: boolean;\n};\n\nexport type { TSNode };\n\nexport function makeSymbolId(filePath: string, name: string, kind: SymbolKind, parentName?: string): string {\n if (parentName) return `${filePath}::${parentName}::${name}#${kind}`;\n return `${filePath}::${name}#${kind}`;\n}\n\nexport function makeFqn(parts: string[]): string {\n return parts.filter(Boolean).join('.');\n}\n\nexport function extractPackageName(root: TSNode): string | undefined {\n for (const child of root.namedChildren) {\n if (child.type === 'package_clause') {\n const nameNode = child.namedChildren.find((c) => c.type === 'package_identifier');\n return nameNode?.text;\n }\n }\n return undefined;\n}\n\nexport function extractSignature(node: TSNode): string {\n const firstLine = node.text.split('\\n')[0].trim();\n const braceIdx = firstLine.indexOf('{');\n if (braceIdx > 0) return firstLine.substring(0, braceIdx).trim();\n return firstLine;\n}\n\nexport function getNodeName(node: TSNode): string | undefined {\n const nameNode = node.childForFieldName('name');\n return nameNode?.text;\n}\n\nexport function extractImportEdges(root: TSNode): RawEdge[] {\n const edges: RawEdge[] = [];\n for (const child of root.namedChildren) {\n if (child.type === 'import_declaration') {\n for (const spec of child.namedChildren) {\n if (spec.type === 'import_spec') {\n const pathNode = spec.childForFieldName('path');\n if (pathNode) {\n const importPath = pathNode.text.replace(/^\"|\"$/g, '');\n const alias = spec.childForFieldName('name')?.text;\n edges.push({\n edgeType: 'imports',\n metadata: { module: importPath, ...(alias ? { alias } : {}) },\n });\n }\n } else if (spec.type === 'import_spec_list') {\n for (const inner of spec.namedChildren) {\n if (inner.type === 'import_spec') {\n const pathNode = inner.childForFieldName('path');\n if (pathNode) {\n const importPath = pathNode.text.replace(/^\"|\"$/g, '');\n const alias = inner.childForFieldName('name')?.text;\n edges.push({\n edgeType: 'imports',\n metadata: { module: importPath, ...(alias ? { alias } : {}) },\n });\n }\n }\n }\n } else if (spec.type === 'interpreted_string_literal') {\n const importPath = spec.text.replace(/^\"|\"$/g, '');\n edges.push({ edgeType: 'imports', metadata: { module: importPath } });\n }\n }\n }\n }\n return edges;\n}\n\nexport function extractStructFields(body: TSNode, filePath: string, structName: string, structSymbolId: string): { symbols: RawSymbol[]; embeds: string[] } {\n const symbols: RawSymbol[] = [];\n const embeds: string[] = [];\n\n for (const child of body.namedChildren) {\n if (child.type === 'field_declaration') {\n const nameNode = child.childForFieldName('name');\n if (nameNode) {\n const name = nameNode.text;\n const typeNode = child.childForFieldName('type');\n const tag = child.namedChildren.find((c) => c.type === 'raw_string_literal' || c.type === 'interpreted_string_literal');\n const meta: Record<string, unknown> = {};\n if (typeNode) meta.type = typeNode.text;\n if (tag) meta.tag = tag.text.replace(/^`|`$/g, '');\n\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'property', structName),\n name,\n kind: 'property',\n parentSymbolId: structSymbolId,\n fqn: makeFqn([structName, name]),\n signature: child.text.trim(),\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n metadata: Object.keys(meta).length > 0 ? meta : undefined,\n });\n } else {\n // Embedded struct (anonymous field)\n const typeNode = child.childForFieldName('type');\n if (typeNode) {\n const typeName = typeNode.text.replace(/^\\*/, '');\n embeds.push(typeName);\n }\n }\n }\n }\n\n return { symbols, embeds };\n}\n\nexport function extractInterfaceMethods(body: TSNode, filePath: string, ifaceName: string, ifaceSymbolId: string): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n for (const child of body.namedChildren) {\n if (child.type === 'method_spec') {\n const name = getNodeName(child);\n if (!name) continue;\n symbols.push({\n symbolId: makeSymbolId(filePath, name, 'method', ifaceName),\n name,\n kind: 'method',\n parentSymbolId: ifaceSymbolId,\n fqn: makeFqn([ifaceName, name]),\n signature: child.text.trim(),\n byteStart: child.startIndex,\n byteEnd: child.endIndex,\n lineStart: child.startPosition.row + 1,\n lineEnd: child.endPosition.row + 1,\n });\n }\n }\n return symbols;\n}\n","/**\n * LaravelPlugin — Framework plugin for Laravel applications.\n * Orchestrates route, Eloquent, migration, FormRequest, event, and middleware extraction.\n *\n * Supports Laravel 6–13:\n * - L6-8: string controller syntax, Route::namespace(), Kernel.php middleware\n * - L8+: class array syntax, invokable controllers\n * - L9+: Route::controller() groups\n * - L11+: bootstrap/app.php (withRouting, withMiddleware)\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\nimport { extractRoutes } from './routes.js';\nimport { extractEloquentModel } from './eloquent.js';\nimport { extractMigrations } from './migrations.js';\nimport { extractFormRequest, detectFormRequestUsage } from './requests.js';\nimport { extractEventListeners, detectEventDispatches } from './events.js';\nimport {\n extractLivewireComponent,\n extractLivewireBladeUsages,\n extractWireDirectives,\n resolveComponentName,\n type LivewireComponentInfo,\n} from './livewire.js';\nimport {\n extractFilamentResource,\n extractFilamentRelationManager,\n extractFilamentPanel,\n extractFilamentWidget,\n} from './filament.js';\nimport { extractNovaResource, extractNovaMetric } from './nova.js';\nimport {\n extractBroadcastingEvent,\n extractChannelAuthorizations,\n} from './broadcasting.js';\nimport { extractDataClass, buildDataClassEdges, extractInertiaDataProps } from './laravel-data.js';\nimport {\n extractFeatureDefinitions,\n extractFeatureUsages,\n extractFeatureBladeUsages,\n extractFeatureMiddlewareUsages,\n} from './pennant.js';\nimport {\n parseKernelMiddleware,\n parseBootstrapMiddleware,\n parseRouteServiceProviderNamespace,\n parseBootstrapRouting,\n type MiddlewareConfig,\n} from './middleware.js';\n\nexport class LaravelPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'laravel',\n version: '1.0.0',\n priority: 0,\n dependencies: [],\n };\n\n /** Cached middleware configuration (populated during extractNodes). */\n private middlewareConfig: MiddlewareConfig | null = null;\n\n /** Controller namespace from RouteServiceProvider (Laravel 6-8). */\n private controllerNamespace: string | null = null;\n\n /** Route file paths from bootstrap/app.php (Laravel 11+). */\n private bootstrapRouting: Record<string, string> | null = null;\n\n /** Whether livewire/livewire is detected as a dependency. */\n private hasLivewire = false;\n\n /** Detected Livewire version (2 or 3), null if not detected. */\n private livewireVersion: 2 | 3 | null = null;\n\n /** Whether filament/filament or filament/support is detected. */\n private hasFilament = false;\n\n /** Whether laravel/nova is detected. */\n private hasNova = false;\n\n /** Whether spatie/laravel-data is detected. */\n private hasLaravelData = false;\n\n /** Whether laravel/reverb or pusher/pusher-php-server is detected. */\n private hasBroadcasting = false;\n\n /** Whether laravel/pennant is detected. */\n private hasPennant = false;\n\n detect(ctx: ProjectContext): boolean {\n // Check if composer.json has laravel/framework in require\n let deps: Record<string, string> | undefined;\n\n if (ctx.composerJson) {\n deps = ctx.composerJson.require as Record<string, string> | undefined;\n } else {\n // Fallback: read composer.json from disk\n try {\n const composerPath = path.join(ctx.rootPath, 'composer.json');\n const content = fs.readFileSync(composerPath, 'utf-8');\n const json = JSON.parse(content);\n deps = json.require as Record<string, string> | undefined;\n } catch {\n return false;\n }\n }\n\n if (!deps?.['laravel/framework']) return false;\n\n // Detect Nova\n if (deps['laravel/nova']) {\n this.hasNova = true;\n }\n\n // Detect Filament\n if (deps['filament/filament'] || deps['filament/support']) {\n this.hasFilament = true;\n }\n\n // Detect Livewire\n if (deps['livewire/livewire']) {\n this.hasLivewire = true;\n // Detect v2 vs v3 from version constraint\n const lwVersion = deps['livewire/livewire'];\n this.livewireVersion = /^\\^?3|^3/.test(lwVersion) ? 3 : 2;\n }\n\n // Detect laravel-data\n if (deps['spatie/laravel-data']) {\n this.hasLaravelData = true;\n }\n\n // Detect Broadcasting (Reverb or Pusher)\n if (deps['laravel/reverb'] || deps['pusher/pusher-php-server']) {\n this.hasBroadcasting = true;\n }\n\n // Detect Pennant\n if (deps['laravel/pennant']) {\n this.hasPennant = true;\n }\n\n return true;\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'routes_to', category: 'laravel', description: 'Route -> Controller' },\n { name: 'has_many', category: 'laravel', description: 'Eloquent hasMany' },\n { name: 'belongs_to', category: 'laravel', description: 'Eloquent belongsTo' },\n { name: 'belongs_to_many', category: 'laravel', description: 'Eloquent belongsToMany' },\n { name: 'has_one', category: 'laravel', description: 'Eloquent hasOne' },\n { name: 'morphs_to', category: 'laravel', description: 'Eloquent morphTo' },\n { name: 'validates_with', category: 'laravel', description: 'Controller -> FormRequest' },\n { name: 'dispatches', category: 'laravel', description: 'Dispatches event/job' },\n { name: 'listens_to', category: 'laravel', description: 'Listener -> Event' },\n { name: 'middleware_guards', category: 'laravel', description: 'Route -> Middleware' },\n { name: 'migrates', category: 'laravel', description: 'Migration -> table' },\n // Nova edges\n { name: 'nova_resource_for', category: 'nova', description: 'Nova Resource → Eloquent Model' },\n { name: 'nova_field_relationship', category: 'nova', description: 'Nova Resource → related Nova Resource via field' },\n { name: 'nova_action_on', category: 'nova', description: 'Action → Resource' },\n { name: 'nova_filter_on', category: 'nova', description: 'Filter → Resource' },\n { name: 'nova_lens_on', category: 'nova', description: 'Lens → Resource' },\n { name: 'nova_metric_queries', category: 'nova', description: 'Metric → Eloquent Model' },\n // Filament edges\n { name: 'filament_resource_for', category: 'filament', description: 'Resource → Eloquent Model' },\n { name: 'filament_relation_manager', category: 'filament', description: 'Resource → RelationManager' },\n { name: 'filament_form_relationship', category: 'filament', description: 'Form field →relationship() → Model' },\n { name: 'filament_page_for', category: 'filament', description: 'Page registered on Resource' },\n { name: 'filament_panel_registers', category: 'filament', description: 'PanelProvider → Resource/Page/Widget' },\n { name: 'filament_widget_queries', category: 'filament', description: 'Widget → Eloquent Model' },\n // Livewire edges\n { name: 'livewire_renders', category: 'livewire', description: 'Component class → Blade view' },\n { name: 'livewire_dispatches', category: 'livewire', description: 'Component dispatches event' },\n { name: 'livewire_listens', category: 'livewire', description: 'Component listens for event' },\n { name: 'livewire_child_of', category: 'livewire', description: 'Blade <livewire:child/> → Component' },\n { name: 'livewire_uses_model', category: 'livewire', description: 'Component → Eloquent Model' },\n { name: 'livewire_form', category: 'livewire', description: 'Component → Form class (v3)' },\n { name: 'livewire_action', category: 'livewire', description: 'wire:click → Component method' },\n // Pennant edges\n { name: 'feature_defined_in', category: 'pennant', description: 'Feature flag defined via Feature::define()' },\n { name: 'feature_checked_by', category: 'pennant', description: 'Feature flag checked in PHP/Blade' },\n { name: 'feature_gates_route', category: 'pennant', description: 'Route protected by features middleware' },\n // Broadcasting edges\n { name: 'broadcasts_on', category: 'broadcasting', description: 'Event broadcasts on a channel' },\n { name: 'channel_authorized_by', category: 'broadcasting', description: 'Channel authorization callback or class' },\n { name: 'broadcast_as', category: 'broadcasting', description: 'Event broadcast name override' },\n // laravel-data edges\n { name: 'data_wraps', category: 'laravel-data', description: 'Data class wraps an Eloquent model' },\n { name: 'data_property_type', category: 'laravel-data', description: 'Data class property references another Data class' },\n { name: 'data_collection', category: 'laravel-data', description: 'DataCollection<T> references a Data class' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'php') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n edges: [],\n routes: [],\n migrations: [],\n warnings: [],\n };\n\n // Kernel.php — middleware config (Laravel 6-10)\n if (this.isKernelFile(filePath)) {\n this.middlewareConfig = parseKernelMiddleware(source);\n result.frameworkRole = 'middleware_config';\n }\n\n // bootstrap/app.php — middleware + routing config (Laravel 11+)\n if (this.isBootstrapAppFile(filePath)) {\n this.middlewareConfig = parseBootstrapMiddleware(source);\n this.bootstrapRouting = parseBootstrapRouting(source);\n result.frameworkRole = 'bootstrap_config';\n }\n\n // RouteServiceProvider — controller namespace (Laravel 6-8)\n if (this.isRouteServiceProvider(filePath)) {\n this.controllerNamespace = parseRouteServiceProviderNamespace(source);\n result.frameworkRole = 'route_provider';\n }\n\n // Route files\n if (this.isRouteFile(filePath)) {\n const routeResult = extractRoutes(source, filePath);\n result.routes = routeResult.routes;\n result.frameworkRole = 'route';\n if (routeResult.warnings.length > 0) {\n result.warnings = routeResult.warnings;\n }\n }\n\n // Migration files\n if (this.isMigrationFile(filePath)) {\n const migResult = extractMigrations(source, filePath);\n result.migrations = migResult.migrations;\n result.frameworkRole = 'migration';\n }\n\n // Model files — store metadata for pass 2\n const modelInfo = extractEloquentModel(source, filePath);\n if (modelInfo) {\n result.frameworkRole = 'model';\n }\n\n // FormRequest files\n const requestInfo = extractFormRequest(source);\n if (requestInfo) {\n result.frameworkRole = 'form_request';\n }\n\n // EventServiceProvider\n if (filePath.includes('EventServiceProvider')) {\n result.frameworkRole = 'event_provider';\n }\n\n // Nova files\n if (this.hasNova) {\n this.processNovaNode(source, filePath, result);\n }\n\n // Filament files\n if (this.hasFilament) {\n this.processFilamentNode(source, filePath, result);\n }\n\n // Livewire component files\n if (this.hasLivewire && this.isLivewireFile(filePath)) {\n const componentInfo = extractLivewireComponent(source, filePath);\n if (componentInfo) {\n result.frameworkRole = 'livewire_component';\n result.edges = result.edges ?? [];\n // Attach component metadata for pass 2 via edges with FQN metadata\n result.edges.push({\n edgeType: 'livewire_renders',\n metadata: {\n sourceFqn: componentInfo.fqn,\n targetViewPath: componentInfo.viewName\n ? `resources/views/${componentInfo.viewName.replace(/\\./g, '/')}.blade.php`\n : componentInfo.conventionViewPath,\n viewName: componentInfo.viewName,\n convention: !componentInfo.viewName,\n },\n });\n for (const dispatch of componentInfo.dispatches) {\n result.edges.push({\n edgeType: 'livewire_dispatches',\n metadata: {\n sourceFqn: componentInfo.fqn,\n eventName: dispatch.eventName,\n method: dispatch.method,\n },\n });\n }\n for (const listener of componentInfo.listeners) {\n result.edges.push({\n edgeType: 'livewire_listens',\n metadata: {\n sourceFqn: componentInfo.fqn,\n eventName: listener.eventName,\n handlerMethod: listener.handlerMethod,\n },\n });\n }\n if (componentInfo.formProperty) {\n result.edges.push({\n edgeType: 'livewire_form',\n metadata: {\n sourceFqn: componentInfo.fqn,\n targetFqn: componentInfo.formProperty.formClass,\n propertyName: componentInfo.formProperty.propertyName,\n },\n });\n }\n for (const prop of componentInfo.properties) {\n if (prop.type && /\\\\Models\\\\/.test(prop.type)) {\n result.edges.push({\n edgeType: 'livewire_uses_model',\n metadata: {\n sourceFqn: componentInfo.fqn,\n targetFqn: prop.type,\n propertyName: prop.name,\n },\n });\n }\n }\n }\n }\n\n // Broadcasting events\n if (this.hasBroadcasting) {\n const eventInfo = extractBroadcastingEvent(source, filePath);\n if (eventInfo) {\n result.frameworkRole = 'broadcasting_event';\n result.edges = result.edges ?? [];\n for (const ch of eventInfo.channels) {\n result.edges.push({\n edgeType: 'broadcasts_on',\n metadata: { sourceFqn: eventInfo.fqn, channelName: ch.name, channelType: ch.type },\n });\n }\n if (eventInfo.broadcastAs) {\n result.edges.push({\n edgeType: 'broadcast_as',\n metadata: { sourceFqn: eventInfo.fqn, broadcastAs: eventInfo.broadcastAs },\n });\n }\n }\n // Channel authorization in channels.php\n if (filePath.endsWith('channels.php')) {\n const mappings = extractChannelAuthorizations(source);\n result.edges = result.edges ?? [];\n for (const m of mappings) {\n result.edges.push({\n edgeType: 'channel_authorized_by',\n metadata: { pattern: m.pattern, authClass: m.authClass },\n });\n }\n }\n }\n\n // Pennant feature flags\n if (this.hasPennant) {\n result.edges = result.edges ?? [];\n const defs = extractFeatureDefinitions(source, filePath);\n for (const def of defs) {\n result.edges.push({\n edgeType: 'feature_defined_in',\n metadata: { featureName: def.name, filePath: def.location, line: def.line },\n });\n }\n const usages = extractFeatureUsages(source);\n for (const u of usages) {\n result.edges.push({\n edgeType: 'feature_checked_by',\n metadata: { featureName: u.name, filePath, line: u.line, usageType: u.usageType },\n });\n }\n const middlewareUsages = extractFeatureMiddlewareUsages(source);\n for (const u of middlewareUsages) {\n result.edges.push({\n edgeType: 'feature_gates_route',\n metadata: { featureName: u.name, filePath, line: u.line },\n });\n }\n }\n\n // laravel-data classes\n if (this.hasLaravelData) {\n const dataInfo = extractDataClass(source, filePath);\n if (dataInfo) {\n result.frameworkRole = 'data_class';\n result.edges = result.edges ?? [];\n result.edges.push(...buildDataClassEdges(dataInfo));\n }\n }\n\n // Detect event dispatches in any file\n const dispatches = detectEventDispatches(source);\n if (dispatches.length > 0) {\n // Store for pass 2\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n const files = ctx.getAllFiles();\n\n // Build a file-path → file map for Livewire view resolution\n const fileMap = new Map<string, { id: number; path: string }>();\n for (const f of files) {\n fileMap.set(f.path, f);\n }\n\n for (const file of files) {\n const source = ctx.readFile(file.path);\n if (!source) continue;\n\n if (file.language === 'php') {\n // Resolve Eloquent relationships\n this.resolveEloquentEdges(source, file, ctx, edges);\n\n // Resolve FormRequest -> Controller edges\n this.resolveFormRequestEdges(source, file, ctx, edges);\n\n // Resolve Event listener edges\n this.resolveEventEdges(source, file, ctx, edges);\n\n // Resolve event dispatch edges\n this.resolveDispatchEdges(source, file, ctx, edges);\n\n // Resolve Livewire PHP-side edges\n if (this.hasLivewire) {\n this.resolveLivewirePhpEdges(source, file, ctx, edges, fileMap);\n }\n\n // Resolve Nova edges\n if (this.hasNova) {\n this.resolveNovaEdges(source, file, ctx, edges);\n }\n\n // Resolve Filament edges\n if (this.hasFilament) {\n this.resolveFilamentEdges(source, file, ctx, edges);\n }\n }\n\n // Resolve Livewire Blade-side edges (<livewire:name/>, wire:click)\n if (this.hasLivewire && file.path.endsWith('.blade.php')) {\n this.resolveLivewireBladeEdges(source, file, ctx, edges);\n }\n\n // Pennant @feature directives in Blade\n if (this.hasPennant && file.path.endsWith('.blade.php')) {\n const bladeUsages = extractFeatureBladeUsages(source);\n for (const usage of bladeUsages) {\n edges.push({\n edgeType: 'feature_checked_by',\n metadata: { featureName: usage.name, filePath: file.path, line: usage.line, usageType: 'blade' },\n });\n }\n }\n }\n\n return ok(edges);\n }\n\n /** Get the parsed middleware config (for use by tools like get_request_flow). */\n getMiddlewareConfig(): MiddlewareConfig | null {\n return this.middlewareConfig;\n }\n\n /** Get the controller namespace from RouteServiceProvider (Laravel 6-8). */\n getControllerNamespace(): string | null {\n return this.controllerNamespace;\n }\n\n /** Get bootstrap routing config (Laravel 11+). */\n getBootstrapRouting(): Record<string, string> | null {\n return this.bootstrapRouting;\n }\n\n /**\n * Resolve a middleware alias to its class FQN.\n * Returns the alias itself if no resolution found.\n */\n resolveMiddlewareAlias(alias: string): string {\n if (!this.middlewareConfig) return alias;\n return this.middlewareConfig.aliases[alias] ?? alias;\n }\n\n /**\n * Get the full middleware chain for a route, resolving aliases.\n * Combines route-level middleware with group middleware.\n */\n getMiddlewareChain(routeMiddleware?: string[]): string[] {\n if (!routeMiddleware || routeMiddleware.length === 0) return [];\n return routeMiddleware.map((m) => {\n const baseName = m.split(':')[0]; // 'auth:sanctum' -> 'auth'\n const resolved = this.resolveMiddlewareAlias(baseName);\n return resolved !== baseName ? `${resolved}${m.includes(':') ? ':' + m.split(':').slice(1).join(':') : ''}` : m;\n });\n }\n\n private resolveEloquentEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n const modelInfo = extractEloquentModel(source, file.path);\n if (!modelInfo) return;\n\n const sourceSymbol = ctx.getSymbolByFqn(modelInfo.fqn);\n if (!sourceSymbol) return;\n\n for (const rel of modelInfo.relationships) {\n const targetSymbol = ctx.getSymbolByFqn(rel.relatedClass);\n if (!targetSymbol) continue;\n\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: sourceSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: targetSymbol.id,\n edgeType: rel.edgeType,\n metadata: {\n method: rel.methodName,\n relationType: rel.type,\n },\n });\n }\n }\n\n private resolveFormRequestEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n const usages = detectFormRequestUsage(source);\n if (usages.length === 0) return;\n\n // Find the class in this file\n const symbols = ctx.getSymbolsByFile(file.id);\n const controllerClass = symbols.find((s) => s.kind === 'class');\n if (!controllerClass) return;\n\n for (const usage of usages) {\n const methodSymbol = symbols.find(\n (s) => s.kind === 'method' && s.name === usage.methodName,\n );\n if (!methodSymbol) continue;\n\n const requestSymbol = ctx.getSymbolByFqn(usage.requestClass);\n if (!requestSymbol) continue;\n\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: methodSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: requestSymbol.id,\n edgeType: 'validates_with',\n metadata: { method: usage.methodName },\n });\n }\n }\n\n private resolveEventEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n const mappings = extractEventListeners(source);\n if (mappings.length === 0) return;\n\n for (const mapping of mappings) {\n const eventSymbol = ctx.getSymbolByFqn(mapping.eventClass);\n if (!eventSymbol) continue;\n\n for (const listenerFqn of mapping.listenerClasses) {\n const listenerSymbol = ctx.getSymbolByFqn(listenerFqn);\n if (!listenerSymbol) continue;\n\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: listenerSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: eventSymbol.id,\n edgeType: 'listens_to',\n });\n }\n }\n }\n\n private resolveDispatchEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n const dispatches = detectEventDispatches(source);\n if (dispatches.length === 0) return;\n\n // Find the class in this file\n const symbols = ctx.getSymbolsByFile(file.id);\n const cls = symbols.find((s) => s.kind === 'class');\n if (!cls) return;\n\n for (const eventFqn of dispatches) {\n const eventSymbol = ctx.getSymbolByFqn(eventFqn);\n if (!eventSymbol) continue;\n\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: cls.id,\n targetNodeType: 'symbol',\n targetRefId: eventSymbol.id,\n edgeType: 'dispatches',\n });\n }\n }\n\n private isRouteFile(filePath: string): boolean {\n return /routes\\/[\\w-]+\\.php$/.test(filePath);\n }\n\n private isMigrationFile(filePath: string): boolean {\n return filePath.includes('database/migrations/');\n }\n\n private isKernelFile(filePath: string): boolean {\n return /app\\/Http\\/Kernel\\.php$/.test(filePath);\n }\n\n private isBootstrapAppFile(filePath: string): boolean {\n return /bootstrap\\/app\\.php$/.test(filePath);\n }\n\n private isRouteServiceProvider(filePath: string): boolean {\n return /Providers\\/RouteServiceProvider\\.php$/.test(filePath);\n }\n\n private processNovaNode(\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n result.edges = result.edges ?? [];\n\n const resource = extractNovaResource(source, filePath);\n if (resource) {\n result.frameworkRole = 'nova_resource';\n if (resource.modelFqn) {\n result.edges.push({ edgeType: 'nova_resource_for', metadata: { sourceFqn: resource.fqn, targetFqn: resource.modelFqn } });\n }\n for (const rel of resource.fieldRelationships) {\n result.edges.push({ edgeType: 'nova_field_relationship', metadata: { sourceFqn: resource.fqn, targetFqn: rel.targetResourceFqn, fieldType: rel.fieldType } });\n }\n for (const a of resource.actions) {\n result.edges.push({ edgeType: 'nova_action_on', metadata: { sourceFqn: a, targetFqn: resource.fqn } });\n }\n for (const f of resource.filters) {\n result.edges.push({ edgeType: 'nova_filter_on', metadata: { sourceFqn: f, targetFqn: resource.fqn } });\n }\n for (const l of resource.lenses) {\n result.edges.push({ edgeType: 'nova_lens_on', metadata: { sourceFqn: l, targetFqn: resource.fqn } });\n }\n return;\n }\n\n const metric = extractNovaMetric(source, filePath);\n if (metric) {\n result.frameworkRole = 'nova_metric';\n for (const m of metric.queriedModels) {\n result.edges.push({ edgeType: 'nova_metric_queries', metadata: { sourceFqn: metric.fqn, targetFqn: m } });\n }\n }\n }\n\n private resolveNovaEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n const resource = extractNovaResource(source, file.path);\n if (resource) {\n const sourceSymbol = ctx.getSymbolByFqn(resource.fqn);\n if (!sourceSymbol) return;\n\n if (resource.modelFqn) {\n const modelSymbol = ctx.getSymbolByFqn(resource.modelFqn);\n if (modelSymbol) {\n edges.push({ sourceNodeType: 'symbol', sourceRefId: sourceSymbol.id, targetNodeType: 'symbol', targetRefId: modelSymbol.id, edgeType: 'nova_resource_for' });\n }\n }\n for (const rel of resource.fieldRelationships) {\n const targetSymbol = ctx.getSymbolByFqn(rel.targetResourceFqn);\n if (targetSymbol) {\n edges.push({ sourceNodeType: 'symbol', sourceRefId: sourceSymbol.id, targetNodeType: 'symbol', targetRefId: targetSymbol.id, edgeType: 'nova_field_relationship', metadata: { fieldType: rel.fieldType } });\n }\n }\n return;\n }\n\n const metric = extractNovaMetric(source, file.path);\n if (metric) {\n const metricSymbol = ctx.getSymbolByFqn(metric.fqn);\n if (!metricSymbol) return;\n for (const modelFqn of metric.queriedModels) {\n const modelSymbol = ctx.getSymbolByFqn(modelFqn);\n if (modelSymbol) {\n edges.push({ sourceNodeType: 'symbol', sourceRefId: metricSymbol.id, targetNodeType: 'symbol', targetRefId: modelSymbol.id, edgeType: 'nova_metric_queries' });\n }\n }\n }\n }\n\n private processFilamentNode(\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n result.edges = result.edges ?? [];\n\n const resource = extractFilamentResource(source, filePath);\n if (resource) {\n result.frameworkRole = 'filament_resource';\n if (resource.modelFqn) {\n result.edges.push({ edgeType: 'filament_resource_for', metadata: { sourceFqn: resource.fqn, targetFqn: resource.modelFqn } });\n }\n for (const rm of resource.relationManagers) {\n result.edges.push({ edgeType: 'filament_relation_manager', metadata: { sourceFqn: resource.fqn, targetFqn: rm } });\n }\n for (const rel of resource.formRelationships) {\n result.edges.push({ edgeType: 'filament_form_relationship', metadata: { sourceFqn: resource.fqn, relationName: rel.relationName } });\n }\n return;\n }\n\n const rm = extractFilamentRelationManager(source, filePath);\n if (rm) {\n result.frameworkRole = 'filament_relation_manager';\n return;\n }\n\n const panel = extractFilamentPanel(source, filePath);\n if (panel) {\n result.frameworkRole = 'filament_panel';\n for (const fqn of [...panel.resources, ...panel.pages, ...panel.widgets]) {\n result.edges.push({ edgeType: 'filament_panel_registers', metadata: { sourceFqn: panel.fqn, targetFqn: fqn, panelId: panel.panelId } });\n }\n return;\n }\n\n const widget = extractFilamentWidget(source, filePath);\n if (widget) {\n result.frameworkRole = 'filament_widget';\n const targets = [...(widget.modelFqn ? [widget.modelFqn] : []), ...widget.queriedModels];\n for (const modelFqn of [...new Set(targets)]) {\n result.edges.push({ edgeType: 'filament_widget_queries', metadata: { sourceFqn: widget.fqn, targetFqn: modelFqn } });\n }\n }\n }\n\n private resolveFilamentEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n // Resource → Model\n const resource = extractFilamentResource(source, file.path);\n if (resource) {\n if (resource.modelFqn) {\n const sourceSymbol = ctx.getSymbolByFqn(resource.fqn);\n const targetSymbol = ctx.getSymbolByFqn(resource.modelFqn);\n if (sourceSymbol && targetSymbol) {\n edges.push({\n sourceNodeType: 'symbol', sourceRefId: sourceSymbol.id,\n targetNodeType: 'symbol', targetRefId: targetSymbol.id,\n edgeType: 'filament_resource_for',\n });\n }\n }\n // Resource → RelationManagers\n const resourceSymbol = ctx.getSymbolByFqn(resource.fqn);\n if (resourceSymbol) {\n for (const rmFqn of resource.relationManagers) {\n const rmSymbol = ctx.getSymbolByFqn(rmFqn);\n if (rmSymbol) {\n edges.push({\n sourceNodeType: 'symbol', sourceRefId: resourceSymbol.id,\n targetNodeType: 'symbol', targetRefId: rmSymbol.id,\n edgeType: 'filament_relation_manager',\n });\n }\n }\n }\n return;\n }\n\n // Widget → Model\n const widget = extractFilamentWidget(source, file.path);\n if (widget) {\n const widgetSymbol = ctx.getSymbolByFqn(widget.fqn);\n if (!widgetSymbol) return;\n const targets = [...(widget.modelFqn ? [widget.modelFqn] : []), ...widget.queriedModels];\n for (const modelFqn of [...new Set(targets)]) {\n const modelSymbol = ctx.getSymbolByFqn(modelFqn);\n if (!modelSymbol) continue;\n edges.push({\n sourceNodeType: 'symbol', sourceRefId: widgetSymbol.id,\n targetNodeType: 'symbol', targetRefId: modelSymbol.id,\n edgeType: 'filament_widget_queries',\n });\n }\n }\n }\n\n private isLivewireFile(filePath: string): boolean {\n // v3: app/Livewire/**/*.php\n // v2: app/Http/Livewire/**/*.php\n return /app\\/(?:Http\\/)?Livewire\\//.test(filePath);\n }\n\n private resolveLivewirePhpEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n fileMap: Map<string, { id: number; path: string }>,\n ): void {\n const componentInfo = extractLivewireComponent(source, file.path);\n if (!componentInfo) return;\n\n const sourceSymbol = ctx.getSymbolByFqn(componentInfo.fqn);\n if (!sourceSymbol) return;\n\n // livewire_renders: Component → Blade view file\n const viewPath = componentInfo.viewName\n ? `resources/views/${componentInfo.viewName.replace(/\\./g, '/')}.blade.php`\n : componentInfo.conventionViewPath;\n const viewFile = fileMap.get(viewPath);\n if (viewFile) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: sourceSymbol.id,\n targetNodeType: 'file',\n targetRefId: viewFile.id,\n edgeType: 'livewire_renders',\n metadata: { viewPath, convention: !componentInfo.viewName },\n });\n }\n\n // livewire_dispatches\n for (const dispatch of componentInfo.dispatches) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: sourceSymbol.id,\n edgeType: 'livewire_dispatches',\n metadata: { eventName: dispatch.eventName, method: dispatch.method },\n });\n }\n\n // livewire_listens\n for (const listener of componentInfo.listeners) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: sourceSymbol.id,\n edgeType: 'livewire_listens',\n metadata: { eventName: listener.eventName, handlerMethod: listener.handlerMethod },\n });\n }\n\n // livewire_form: Component → Form class\n if (componentInfo.formProperty) {\n const formSymbol = ctx.getSymbolByFqn(componentInfo.formProperty.formClass);\n if (formSymbol) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: sourceSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: formSymbol.id,\n edgeType: 'livewire_form',\n metadata: { propertyName: componentInfo.formProperty.propertyName },\n });\n }\n }\n\n // livewire_uses_model: Component → Eloquent Model\n for (const prop of componentInfo.properties) {\n if (!prop.type || !/\\\\Models\\\\/.test(prop.type)) continue;\n const modelSymbol = ctx.getSymbolByFqn(prop.type);\n if (!modelSymbol) continue;\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: sourceSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: modelSymbol.id,\n edgeType: 'livewire_uses_model',\n metadata: { propertyName: prop.name },\n });\n }\n }\n\n private resolveLivewireBladeEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n const version = this.livewireVersion ?? 3;\n\n // <livewire:component-name /> and @livewire('component-name')\n const usages = extractLivewireBladeUsages(source);\n for (const usage of usages) {\n const componentFqn = resolveComponentName(usage.componentName, version);\n const componentSymbol = ctx.getSymbolByFqn(componentFqn);\n if (!componentSymbol) continue;\n\n edges.push({\n sourceNodeType: 'file',\n sourceRefId: file.id,\n targetNodeType: 'symbol',\n targetRefId: componentSymbol.id,\n edgeType: 'livewire_child_of',\n metadata: { componentName: usage.componentName, line: usage.line, syntax: usage.syntax },\n });\n }\n\n // wire:click=\"method\" → livewire_action\n const wireDirectives = extractWireDirectives(source);\n for (const directive of wireDirectives) {\n if (directive.directive === 'model') continue; // model is informational\n edges.push({\n sourceNodeType: 'file',\n sourceRefId: file.id,\n edgeType: 'livewire_action',\n metadata: { directive: directive.directive, method: directive.value, line: directive.line },\n });\n }\n }\n}\n","/**\n * Laravel route extraction from route files.\n * Parses Route::get/post/resource/apiResource calls using regex on PHP source.\n *\n * Supports:\n * - Class array syntax: Route::get('/path', [Controller::class, 'method']) (L8+)\n * - String syntax: Route::get('/path', 'Controller@method') (L6-8)\n * - Invokable: Route::get('/path', Controller::class) (L8+)\n * - Route::resource / Route::apiResource\n * - Route::controller(X::class)->group(...) (L9+)\n * - Route::namespace('Admin')->group(...) (L6-8)\n * - Route::middleware(...)->group(...)\n * - Route::prefix(...)->... chains\n */\nimport type { RawRoute } from '../../../../plugin-api/types.js';\n\n/** HTTP methods supported by Laravel routing. */\nconst HTTP_METHODS = ['get', 'post', 'put', 'patch', 'delete', 'options', 'any'];\n\n/** Resource route methods generated by Route::resource(). */\nconst RESOURCE_METHODS = [\n { method: 'GET', suffix: '', action: 'index' },\n { method: 'GET', suffix: '/create', action: 'create' },\n { method: 'POST', suffix: '', action: 'store' },\n { method: 'GET', suffix: '/{id}', action: 'show' },\n { method: 'GET', suffix: '/{id}/edit', action: 'edit' },\n { method: 'PUT', suffix: '/{id}', action: 'update' },\n { method: 'DELETE', suffix: '/{id}', action: 'destroy' },\n];\n\n/** API resource methods (no create/edit views). */\nconst API_RESOURCE_METHODS = RESOURCE_METHODS.filter(\n (m) => m.action !== 'create' && m.action !== 'edit',\n);\n\nexport interface RouteExtractionResult {\n routes: RawRoute[];\n warnings: string[];\n}\n\n/**\n * Context accumulated from group wrappers (namespace, prefix, middleware, controller).\n */\ninterface GroupContext {\n namespace?: string;\n prefix?: string;\n middleware?: string[];\n controller?: string;\n}\n\n/**\n * Extract routes from a PHP route file source.\n * Handles all Laravel route definition patterns from L6 to L13.\n */\nexport function extractRoutes(\n source: string,\n filePath: string,\n): RouteExtractionResult {\n const routes: RawRoute[] = [];\n const warnings: string[] = [];\n\n // Extract use statements for class resolution\n const useMap = buildUseMap(source);\n\n // Process groups recursively, then top-level routes\n processRouteGroups(source, useMap, routes, { });\n\n // Extract top-level simple routes (not inside any group we've already processed)\n extractSimpleRoutes(source, useMap, routes, { });\n\n // Extract top-level resource routes\n extractResourceRoutes(source, useMap, routes, { });\n\n // Apply middleware from Route::middleware(...)->group(...) blocks\n applyMiddlewareGroups(source, routes);\n\n return { routes, warnings };\n}\n\n/** Build a map of short class name -> FQN from `use` statements. */\nfunction buildUseMap(source: string): Map<string, string> {\n const map = new Map<string, string>();\n const useRegex = /use\\s+([\\w\\\\]+?)(?:\\s+as\\s+(\\w+))?;/g;\n let match: RegExpExecArray | null;\n while ((match = useRegex.exec(source)) !== null) {\n const fqn = match[1];\n const alias = match[2] ?? fqn.split('\\\\').pop()!;\n map.set(alias, fqn);\n }\n return map;\n}\n\n/**\n * Resolve a class reference to FQN.\n * Handles:\n * - UserController::class (short name, lookup in useMap)\n * - \\App\\Http\\Controllers\\PostController::class (FQN)\n * - 'UserController@index' string syntax → namespace-aware\n * - Plain string 'UserController' for invokable\n */\nfunction resolveClass(ref: string, useMap: Map<string, string>, namespace?: string): string {\n // ::class syntax: short name\n const shortMatch = ref.match(/^(\\w+)::class$/);\n if (shortMatch) {\n return useMap.get(shortMatch[1]) ?? shortMatch[1];\n }\n\n // ::class syntax: FQN with backslashes\n const fqnMatch = ref.match(/^\\\\?([\\w\\\\]+)::class$/);\n if (fqnMatch) return fqnMatch[1];\n\n // Plain class name (no :: no @) — e.g. from string syntax or invokable\n if (!ref.includes('::') && !ref.includes('@')) {\n // Check if it contains backslashes (already namespaced)\n if (ref.includes('\\\\')) {\n return ref.replace(/^\\\\/, '');\n }\n // Apply namespace context if present\n if (namespace) {\n return `${namespace}\\\\${ref}`;\n }\n return useMap.get(ref) ?? ref;\n }\n\n return ref;\n}\n\n/**\n * Process Route::group() wrappers that carry context (namespace, prefix, middleware, controller).\n *\n * Matches patterns like:\n * - Route::namespace('Admin')->prefix('admin')->group(function () { ... })\n * - Route::controller(UserController::class)->group(function () { ... })\n * - Route::middleware(['auth'])->prefix('api')->group(function () { ... })\n */\nfunction processRouteGroups(\n source: string,\n useMap: Map<string, string>,\n routes: RawRoute[],\n parentCtx: GroupContext,\n): void {\n // Match Route:: chains ending with ->group(function ... { ... })\n // We use a regex that captures the chain before group() and then find the matching body\n const groupStartRegex = /Route::((?:namespace|controller|prefix|middleware|name)\\s*\\([^)]*\\)\\s*->\\s*)*group\\s*\\(\\s*function\\s*\\([^)]*\\)\\s*\\{/g;\n\n // Simpler approach: find specific group patterns\n // 1. Route::namespace('X')->...->group(function () { ... })\n extractNamespaceGroups(source, useMap, routes, parentCtx);\n\n // 2. Route::controller(X::class)->group(function () { ... })\n extractControllerGroups(source, useMap, routes, parentCtx);\n}\n\n/**\n * Extract Route::namespace('Admin')->...->group(function () { ... })\n */\nfunction extractNamespaceGroups(\n source: string,\n useMap: Map<string, string>,\n routes: RawRoute[],\n parentCtx: GroupContext,\n): void {\n const regex = /Route::namespace\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)((?:\\s*->\\s*(?:prefix|middleware|name)\\s*\\([^)]*\\))*)\\s*->\\s*group\\s*\\(\\s*function\\s*\\([^)]*\\)\\s*\\{/g;\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const ns = match[1];\n const chainStr = match[2] || '';\n const bodyStart = match.index + match[0].length;\n const body = extractGroupBody(source, bodyStart);\n if (!body) continue;\n\n const ctx: GroupContext = {\n ...parentCtx,\n namespace: parentCtx.namespace ? `${parentCtx.namespace}\\\\${ns}` : ns,\n };\n\n // Extract prefix from chain\n const prefixMatch = chainStr.match(/prefix\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/);\n if (prefixMatch) {\n ctx.prefix = parentCtx.prefix\n ? `${parentCtx.prefix}/${prefixMatch[1]}`\n : prefixMatch[1];\n }\n\n // Extract middleware from chain\n const mwMatch = chainStr.match(/middleware\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/);\n if (mwMatch) {\n ctx.middleware = [...(parentCtx.middleware ?? []), mwMatch[1]];\n }\n\n // Parse routes inside the group body\n extractSimpleRoutes(body, useMap, routes, ctx);\n extractResourceRoutes(body, useMap, routes, ctx);\n }\n}\n\n/**\n * Extract Route::controller(X::class)->group(function () { ... })\n * Laravel 9+ pattern where method routes only need the action name.\n */\nfunction extractControllerGroups(\n source: string,\n useMap: Map<string, string>,\n routes: RawRoute[],\n parentCtx: GroupContext,\n): void {\n const regex = /Route::controller\\s*\\(\\s*([\\w\\\\]+::class)\\s*\\)((?:\\s*->\\s*(?:prefix|middleware|name)\\s*\\([^)]*\\))*)\\s*->\\s*group\\s*\\(\\s*function\\s*\\([^)]*\\)\\s*\\{/g;\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const controllerFqn = resolveClass(match[1], useMap, parentCtx.namespace);\n const chainStr = match[2] || '';\n const bodyStart = match.index + match[0].length;\n const body = extractGroupBody(source, bodyStart);\n if (!body) continue;\n\n const ctx: GroupContext = {\n ...parentCtx,\n controller: controllerFqn,\n };\n\n // Extract prefix/middleware from chain\n const prefixMatch = chainStr.match(/prefix\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/);\n if (prefixMatch) {\n ctx.prefix = parentCtx.prefix\n ? `${parentCtx.prefix}/${prefixMatch[1]}`\n : prefixMatch[1];\n }\n const mwMatch = chainStr.match(/middleware\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/);\n if (mwMatch) {\n ctx.middleware = [...(parentCtx.middleware ?? []), mwMatch[1]];\n }\n\n // Inside controller groups, routes use short syntax:\n // Route::get('/users', 'index')\n extractControllerGroupRoutes(body, controllerFqn, ctx, routes);\n }\n}\n\n/**\n * Extract routes from inside a Route::controller() group.\n * These routes only specify the action name as a string: Route::get('/path', 'action')\n */\nfunction extractControllerGroupRoutes(\n body: string,\n controllerFqn: string,\n ctx: GroupContext,\n routes: RawRoute[],\n): void {\n const methodPattern = HTTP_METHODS.join('|');\n const regex = new RegExp(\n `Route::(${methodPattern})\\\\s*\\\\(\\\\s*['\"]([^'\"]+)['\"]\\\\s*,\\\\s*['\"]([^'\"]+)['\"]\\\\s*\\\\)([^;]*);`,\n 'g',\n );\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(body)) !== null) {\n const method = match[1].toUpperCase();\n const uri = applyPrefix(match[2], ctx.prefix);\n const action = match[3];\n const chain = match[4];\n\n const name = extractChainedName(chain);\n const chainMiddleware = extractChainedMiddleware(chain);\n const middleware = mergeMiddleware(ctx.middleware, chainMiddleware);\n\n routes.push({\n method,\n uri,\n name: name ?? undefined,\n controllerSymbolId: `${controllerFqn}::${action}`,\n middleware: middleware.length > 0 ? middleware : undefined,\n });\n }\n}\n\n/**\n * Extract Route::get/post/put/patch/delete/any calls.\n * Supports:\n * - [Controller::class, 'method'] array syntax\n * - 'Controller@method' string syntax\n * - Controller::class invokable syntax\n */\nfunction extractSimpleRoutes(\n source: string,\n useMap: Map<string, string>,\n routes: RawRoute[],\n ctx: GroupContext,\n): void {\n const methodPattern = HTTP_METHODS.join('|');\n\n // 1. Array syntax: Route::get('/path', [Controller::class, 'method'])\n const arrayRegex = new RegExp(\n `Route::(${methodPattern})\\\\s*\\\\(\\\\s*['\"]([^'\"]+)['\"]\\\\s*,\\\\s*\\\\[\\\\s*([\\\\w\\\\\\\\]+::class)\\\\s*,\\\\s*['\"]([^'\"]+)['\"]\\\\s*\\\\]\\\\s*\\\\)([^;]*);`,\n 'g',\n );\n\n let match: RegExpExecArray | null;\n while ((match = arrayRegex.exec(source)) !== null) {\n const method = match[1].toUpperCase();\n const uri = applyPrefix(match[2], ctx.prefix);\n const controllerFqn = resolveClass(match[3], useMap, ctx.namespace);\n const action = match[4];\n const chain = match[5];\n\n const name = extractChainedName(chain);\n const chainMiddleware = extractChainedMiddleware(chain);\n const middleware = mergeMiddleware(ctx.middleware, chainMiddleware);\n\n routes.push({\n method,\n uri,\n name: name ?? undefined,\n controllerSymbolId: `${controllerFqn}::${action}`,\n middleware: middleware.length > 0 ? middleware : undefined,\n });\n }\n\n // 2. String syntax: Route::get('/path', 'Controller@method') — Laravel 6-8\n const stringRegex = new RegExp(\n `Route::(${methodPattern})\\\\s*\\\\(\\\\s*['\"]([^'\"]+)['\"]\\\\s*,\\\\s*'([^']+@[^']+)'\\\\s*\\\\)([^;]*);`,\n 'g',\n );\n while ((match = stringRegex.exec(source)) !== null) {\n const method = match[1].toUpperCase();\n const uri = applyPrefix(match[2], ctx.prefix);\n const controllerAction = match[3]; // e.g. 'UserController@index' or 'Admin\\UserController@index'\n const chain = match[4];\n\n const [controllerName, action] = controllerAction.split('@');\n const controllerFqn = resolveClass(controllerName, useMap, ctx.namespace);\n\n const name = extractChainedName(chain);\n const chainMiddleware = extractChainedMiddleware(chain);\n const middleware = mergeMiddleware(ctx.middleware, chainMiddleware);\n\n routes.push({\n method,\n uri,\n name: name ?? undefined,\n controllerSymbolId: `${controllerFqn}::${action}`,\n middleware: middleware.length > 0 ? middleware : undefined,\n });\n }\n\n // 3. Also match string syntax with double quotes\n const stringRegexDQ = new RegExp(\n `Route::(${methodPattern})\\\\s*\\\\(\\\\s*['\"]([^'\"]+)['\"]\\\\s*,\\\\s*\"([^\"]+@[^\"]+)\"\\\\s*\\\\)([^;]*);`,\n 'g',\n );\n while ((match = stringRegexDQ.exec(source)) !== null) {\n const method = match[1].toUpperCase();\n const uri = applyPrefix(match[2], ctx.prefix);\n const controllerAction = match[3];\n const chain = match[4];\n\n const [controllerName, action] = controllerAction.split('@');\n const controllerFqn = resolveClass(controllerName, useMap, ctx.namespace);\n\n const name = extractChainedName(chain);\n const chainMiddleware = extractChainedMiddleware(chain);\n const middleware = mergeMiddleware(ctx.middleware, chainMiddleware);\n\n routes.push({\n method,\n uri,\n name: name ?? undefined,\n controllerSymbolId: `${controllerFqn}::${action}`,\n middleware: middleware.length > 0 ? middleware : undefined,\n });\n }\n\n // 4. Invokable controller: Route::get('/path', Controller::class)\n const invokableRegex = new RegExp(\n `Route::(${methodPattern})\\\\s*\\\\(\\\\s*['\"]([^'\"]+)['\"]\\\\s*,\\\\s*([\\\\w\\\\\\\\]+::class)\\\\s*\\\\)([^;]*);`,\n 'g',\n );\n while ((match = invokableRegex.exec(source)) !== null) {\n const method = match[1].toUpperCase();\n const uri = applyPrefix(match[2], ctx.prefix);\n const controllerFqn = resolveClass(match[3], useMap, ctx.namespace);\n const chain = match[4];\n\n // Check this isn't already captured by array syntax (which would have a comma + bracket after class)\n // The invokable regex only matches when ::class is followed by ) directly\n const name = extractChainedName(chain);\n const chainMiddleware = extractChainedMiddleware(chain);\n const middleware = mergeMiddleware(ctx.middleware, chainMiddleware);\n\n routes.push({\n method,\n uri,\n name: name ?? undefined,\n controllerSymbolId: `${controllerFqn}::__invoke`,\n middleware: middleware.length > 0 ? middleware : undefined,\n });\n }\n}\n\n/** Extract Route::resource and Route::apiResource calls. */\nfunction extractResourceRoutes(\n source: string,\n useMap: Map<string, string>,\n routes: RawRoute[],\n ctx: GroupContext,\n): void {\n // Class-based: Route::resource('posts', PostController::class)\n const classRegex = /Route::(resource|apiResource)\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*,\\s*([\\w\\\\]+::class)\\s*\\)([^;]*);/g;\n\n let match: RegExpExecArray | null;\n while ((match = classRegex.exec(source)) !== null) {\n const type = match[1];\n const prefix = match[2];\n const controllerFqn = resolveClass(match[3], useMap, ctx.namespace);\n const chain = match[4];\n const chainMiddleware = extractChainedMiddleware(chain);\n const middleware = mergeMiddleware(ctx.middleware, chainMiddleware);\n\n const methods = type === 'apiResource' ? API_RESOURCE_METHODS : RESOURCE_METHODS;\n\n for (const rm of methods) {\n const uri = applyPrefix(`/${prefix}${rm.suffix}`, ctx.prefix);\n routes.push({\n method: rm.method,\n uri,\n name: `${prefix}.${rm.action}`,\n controllerSymbolId: `${controllerFqn}::${rm.action}`,\n middleware: middleware.length > 0 ? middleware : undefined,\n });\n }\n }\n\n // String-based: Route::resource('posts', 'PostController') — Laravel 6-8\n const stringRegex = /Route::(resource|apiResource)\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*,\\s*['\"]([^'\"]+)['\"]\\s*\\)([^;]*);/g;\n\n while ((match = stringRegex.exec(source)) !== null) {\n const type = match[1];\n const prefix = match[2];\n const controllerName = match[3];\n const chain = match[4];\n\n // Skip if this looks like a class reference (already handled above)\n if (controllerName.includes('::')) continue;\n\n const controllerFqn = resolveClass(controllerName, useMap, ctx.namespace);\n const chainMiddleware = extractChainedMiddleware(chain);\n const middleware = mergeMiddleware(ctx.middleware, chainMiddleware);\n\n const methods = type === 'apiResource' ? API_RESOURCE_METHODS : RESOURCE_METHODS;\n\n for (const rm of methods) {\n const uri = applyPrefix(`/${prefix}${rm.suffix}`, ctx.prefix);\n routes.push({\n method: rm.method,\n uri,\n name: `${prefix}.${rm.action}`,\n controllerSymbolId: `${controllerFqn}::${rm.action}`,\n middleware: middleware.length > 0 ? middleware : undefined,\n });\n }\n }\n}\n\n/** Extract ->name('...') from method chain. */\nfunction extractChainedName(chain: string): string | null {\n const match = chain.match(/->name\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/);\n return match ? match[1] : null;\n}\n\n/** Extract ->middleware('...') or ->middleware(['...', '...']) from method chain. */\nfunction extractChainedMiddleware(chain: string): string[] {\n const match = chain.match(/->middleware\\s*\\(\\s*(['\"\\[].*?)\\s*\\)/);\n if (!match) return [];\n\n const arg = match[1];\n // Array form: ['auth', 'verified']\n if (arg.startsWith('[')) {\n const items: string[] = [];\n const regex = /['\"]([^'\"]+)['\"]/g;\n let m: RegExpExecArray | null;\n while ((m = regex.exec(arg)) !== null) {\n items.push(m[1]);\n }\n return items;\n }\n\n // Single string: 'auth'\n const single = arg.match(/['\"]([^'\"]+)['\"]/);\n return single ? [single[1]] : [];\n}\n\n/** Apply middleware from Route::middleware(...)->group(...) wrappers to already-extracted routes. */\nfunction applyMiddlewareGroups(source: string, routes: RawRoute[]): void {\n // Match: Route::middleware('auth:sanctum')->group(function () { ... });\n // Also: Route::middleware(['auth', 'verified'])->group(function () { ... });\n const groupRegex = /Route::middleware\\s*\\(\\s*([\\['\"\"][^)]*?)\\s*\\)\\s*->\\s*group\\s*\\(\\s*function\\s*\\([^)]*\\)\\s*\\{/g;\n\n let match: RegExpExecArray | null;\n while ((match = groupRegex.exec(source)) !== null) {\n const mwArg = match[1];\n const groupMiddleware = parseMiddlewareArg(mwArg);\n const bodyStart = match.index + match[0].length;\n const body = extractGroupBody(source, bodyStart);\n if (!body) continue;\n\n // Find routes defined inside this group by matching their URIs in the body\n for (const route of routes) {\n if (body.includes(route.uri)) {\n // Add group middleware, avoiding duplicates\n const existing = route.middleware ?? [];\n const toAdd = groupMiddleware.filter((m) => !existing.includes(m));\n if (toAdd.length > 0) {\n route.middleware = [...toAdd, ...existing];\n }\n }\n }\n }\n}\n\n/** Parse a middleware argument which can be 'name', \"name\", or ['a', 'b']. */\nfunction parseMiddlewareArg(arg: string): string[] {\n const trimmed = arg.trim();\n if (trimmed.startsWith('[')) {\n const items: string[] = [];\n const regex = /['\"]([^'\"]+)['\"]/g;\n let m: RegExpExecArray | null;\n while ((m = regex.exec(trimmed)) !== null) {\n items.push(m[1]);\n }\n return items;\n }\n const single = trimmed.match(/['\"]([^'\"]+)['\"]/);\n return single ? [single[1]] : [];\n}\n\n/**\n * Extract the body of a group closure starting at a given position.\n * Counts braces to find the matching closing brace.\n */\nfunction extractGroupBody(source: string, startIndex: number): string | null {\n let depth = 1;\n let i = startIndex;\n while (i < source.length && depth > 0) {\n if (source[i] === '{') depth++;\n else if (source[i] === '}') depth--;\n i++;\n }\n if (depth !== 0) return null;\n return source.substring(startIndex, i - 1);\n}\n\n/** Prepend prefix to a URI. */\nfunction applyPrefix(uri: string, prefix?: string): string {\n if (!prefix) return uri;\n const normalizedPrefix = prefix.startsWith('/') ? prefix : `/${prefix}`;\n const normalizedUri = uri.startsWith('/') ? uri : `/${uri}`;\n return `${normalizedPrefix}${normalizedUri}`;\n}\n\n/** Merge parent middleware with local middleware, parent first. */\nfunction mergeMiddleware(parent?: string[], local?: string[]): string[] {\n const result = [...(parent ?? [])];\n for (const m of local ?? []) {\n if (!result.includes(m)) {\n result.push(m);\n }\n }\n return result;\n}\n","/**\n * Eloquent model extraction — relationships, fillable, casts, scopes.\n * Uses regex on PHP source to detect relationship method calls and properties.\n */\nimport type { RawEdge } from '../../../../plugin-api/types.js';\n\n/** Relationship types we detect and their corresponding edge types. */\nconst RELATIONSHIP_MAP: Record<string, string> = {\n hasMany: 'has_many',\n belongsTo: 'belongs_to',\n belongsToMany: 'belongs_to_many',\n hasOne: 'has_one',\n morphTo: 'morphs_to',\n morphMany: 'has_many',\n morphOne: 'has_one',\n hasOneThrough: 'has_one',\n hasManyThrough: 'has_many',\n};\n\nexport interface EloquentRelationship {\n methodName: string;\n type: string; // e.g. 'hasMany'\n relatedClass: string; // FQN of related model\n edgeType: string; // e.g. 'has_many'\n}\n\nexport interface EloquentModelInfo {\n className: string;\n namespace: string | undefined;\n fqn: string;\n extendsModel: boolean;\n fillable: string[];\n casts: Record<string, string>;\n scopes: string[];\n relationships: EloquentRelationship[];\n}\n\n/**\n * Check if a PHP source file contains an Eloquent model class.\n * Returns the model info if found, null otherwise.\n */\nexport function extractEloquentModel(\n source: string,\n filePath: string,\n): EloquentModelInfo | null {\n // Check for Model extends\n const classMatch = source.match(\n /class\\s+(\\w+)\\s+extends\\s+(?:\\\\?(?:Illuminate\\\\Database\\\\Eloquent\\\\)?)?Model\\b/,\n );\n if (!classMatch) return null;\n\n const className = classMatch[1];\n const namespace = extractNamespaceFromSource(source);\n const fqn = namespace ? `${namespace}\\\\${className}` : className;\n const useMap = buildUseMap(source);\n\n return {\n className,\n namespace,\n fqn,\n extendsModel: true,\n fillable: extractFillable(source),\n casts: extractCasts(source),\n scopes: extractScopes(source),\n relationships: extractRelationships(source, useMap, namespace),\n };\n}\n\n/** Extract namespace from source. */\nfunction extractNamespaceFromSource(source: string): string | undefined {\n const match = source.match(/namespace\\s+([\\w\\\\]+)\\s*;/);\n return match ? match[1] : undefined;\n}\n\n/** Build a map of short class name -> FQN from use statements. */\nfunction buildUseMap(source: string): Map<string, string> {\n const map = new Map<string, string>();\n const regex = /use\\s+([\\w\\\\]+?)(?:\\s+as\\s+(\\w+))?;/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const fqn = match[1];\n const alias = match[2] ?? fqn.split('\\\\').pop()!;\n map.set(alias, fqn);\n }\n return map;\n}\n\n/** Extract $fillable property values. */\nfunction extractFillable(source: string): string[] {\n const match = source.match(\n /\\$fillable\\s*=\\s*\\[([\\s\\S]*?)\\]/,\n );\n if (!match) return [];\n\n const items: string[] = [];\n const regex = /['\"]([^'\"]+)['\"]/g;\n let m: RegExpExecArray | null;\n while ((m = regex.exec(match[1])) !== null) {\n items.push(m[1]);\n }\n return items;\n}\n\n/** Extract $casts property. */\nfunction extractCasts(source: string): Record<string, string> {\n const match = source.match(\n /\\$casts\\s*=\\s*\\[([\\s\\S]*?)\\]/,\n );\n if (!match) return {};\n\n const casts: Record<string, string> = {};\n const regex = /['\"]([^'\"]+)['\"]\\s*=>\\s*['\"]([^'\"]+)['\"]/g;\n let m: RegExpExecArray | null;\n while ((m = regex.exec(match[1])) !== null) {\n casts[m[1]] = m[2];\n }\n return casts;\n}\n\n/** Extract scope method names (e.g. scopeActive -> active). */\nfunction extractScopes(source: string): string[] {\n const scopes: string[] = [];\n const regex = /public\\s+function\\s+scope(\\w+)\\s*\\(/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n // Convert first char to lowercase: scopeActive -> active\n const name = match[1].charAt(0).toLowerCase() + match[1].slice(1);\n scopes.push(name);\n }\n return scopes;\n}\n\n/** Extract Eloquent relationship method calls. */\nfunction extractRelationships(\n source: string,\n useMap: Map<string, string>,\n namespace: string | undefined,\n): EloquentRelationship[] {\n const relationships: EloquentRelationship[] = [];\n const relTypes = Object.keys(RELATIONSHIP_MAP).join('|');\n\n // Match: public function posts(): HasMany { return $this->hasMany(Post::class); }\n const regex = new RegExp(\n `public\\\\s+function\\\\s+(\\\\w+)\\\\s*\\\\([^)]*\\\\)(?:\\\\s*:\\\\s*\\\\w+)?\\\\s*\\\\{[^}]*\\\\$this->(${relTypes})\\\\s*\\\\(\\\\s*([\\\\w\\\\\\\\]+::class)`,\n 'g',\n );\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const methodName = match[1];\n const relType = match[2];\n const classRef = match[3];\n const edgeType = RELATIONSHIP_MAP[relType];\n\n // Resolve the related class\n const relatedClass = resolveClassRef(classRef, useMap, namespace);\n\n relationships.push({\n methodName,\n type: relType,\n relatedClass,\n edgeType,\n });\n }\n\n return relationships;\n}\n\n/** Resolve a ::class reference to a FQN. */\nfunction resolveClassRef(\n ref: string,\n useMap: Map<string, string>,\n namespace: string | undefined,\n): string {\n // Fully qualified: \\App\\Models\\Post::class\n const fqnMatch = ref.match(/^\\\\?([\\w\\\\]+)::class$/);\n if (fqnMatch && fqnMatch[1].includes('\\\\')) return fqnMatch[1];\n\n // Short name: Post::class\n const shortMatch = ref.match(/^(\\w+)::class$/);\n if (shortMatch) {\n const short = shortMatch[1];\n if (useMap.has(short)) return useMap.get(short)!;\n // Assume same namespace\n if (namespace) return `${namespace}\\\\${short}`;\n return short;\n }\n\n return ref;\n}\n\n/**\n * Build edges from an extracted model's relationships.\n * Maps model FQN -> related model FQN via edge type.\n */\nexport function buildRelationshipEdges(\n modelInfo: EloquentModelInfo,\n): RawEdge[] {\n return modelInfo.relationships.map((rel) => ({\n sourceSymbolId: undefined,\n targetSymbolId: undefined,\n edgeType: rel.edgeType,\n metadata: {\n sourceFqn: modelInfo.fqn,\n targetFqn: rel.relatedClass,\n method: rel.methodName,\n relationType: rel.type,\n },\n }));\n}\n","/**\n * Laravel migration parsing — Schema::create/table/drop extraction.\n * Extracts table names, columns, and timestamps from migration files.\n */\nimport type { RawMigration } from '../../../../plugin-api/types.js';\n\n/** Column type mapping from Laravel Blueprint methods. */\nconst COLUMN_TYPES: Record<string, string> = {\n id: 'bigint',\n bigIncrements: 'bigint',\n increments: 'integer',\n string: 'varchar',\n text: 'text',\n longText: 'longtext',\n mediumText: 'mediumtext',\n integer: 'integer',\n bigInteger: 'bigint',\n smallInteger: 'smallint',\n tinyInteger: 'tinyint',\n float: 'float',\n double: 'double',\n decimal: 'decimal',\n boolean: 'boolean',\n date: 'date',\n dateTime: 'datetime',\n timestamp: 'timestamp',\n time: 'time',\n json: 'json',\n jsonb: 'jsonb',\n binary: 'blob',\n uuid: 'uuid',\n foreignId: 'bigint',\n unsignedBigInteger: 'bigint',\n unsignedInteger: 'integer',\n enum: 'enum',\n timestamps: 'timestamps',\n softDeletes: 'timestamp',\n rememberToken: 'varchar',\n nullableTimestamps: 'timestamps',\n morphs: 'morphs',\n nullableMorphs: 'morphs',\n uuidMorphs: 'morphs',\n};\n\nexport interface MigrationColumn {\n name: string;\n type: string;\n nullable?: boolean;\n unique?: boolean;\n default?: string;\n}\n\nexport interface MigrationExtractionResult {\n migrations: RawMigration[];\n warnings: string[];\n}\n\n/**\n * Extract migration data from a PHP migration file.\n * Only parses the up() method to avoid capturing down() operations.\n */\nexport function extractMigrations(\n source: string,\n filePath: string,\n): MigrationExtractionResult {\n const migrations: RawMigration[] = [];\n const warnings: string[] = [];\n const timestamp = extractTimestamp(filePath);\n\n // Extract only the up() method body to avoid parsing down() method\n const upBody = extractUpMethodBody(source) ?? source;\n\n // Schema::create('table', function (...) { ... })\n extractSchemaCreate(upBody, timestamp, migrations);\n\n // Schema::table('table', function (...) { ... })\n extractSchemaTable(upBody, timestamp, migrations);\n\n // Schema::drop('table') and Schema::dropIfExists('table')\n extractSchemaDrop(upBody, timestamp, migrations);\n\n return { migrations, warnings };\n}\n\n/** Extract the body of the up() method. */\nfunction extractUpMethodBody(source: string): string | null {\n // Match: public function up()... { ... }\n // Use a brace-counting approach to handle nested braces\n const upStart = source.match(/public\\s+function\\s+up\\s*\\([^)]*\\)(?:\\s*:\\s*\\w+)?\\s*\\{/);\n if (!upStart || upStart.index === undefined) return null;\n\n let braceCount = 1;\n let pos = upStart.index + upStart[0].length;\n const start = pos;\n\n while (pos < source.length && braceCount > 0) {\n if (source[pos] === '{') braceCount++;\n else if (source[pos] === '}') braceCount--;\n pos++;\n }\n\n return source.substring(start, pos - 1);\n}\n\n/** Extract timestamp from migration filename (e.g. 2024_01_01_000000_...). */\nexport function extractTimestamp(filePath: string): string | undefined {\n const match = filePath.match(/(\\d{4}_\\d{2}_\\d{2}_\\d{6})/);\n return match ? match[1] : undefined;\n}\n\n/** Parse Schema::create calls. */\nfunction extractSchemaCreate(\n source: string,\n timestamp: string | undefined,\n migrations: RawMigration[],\n): void {\n const regex = /Schema::create\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*,\\s*function\\s*\\([^)]*\\)\\s*\\{([\\s\\S]*?)\\}\\s*\\)/g;\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const tableName = match[1];\n const body = match[2];\n const columns = extractColumns(body);\n\n migrations.push({\n tableName,\n operation: 'create',\n columns,\n timestamp,\n });\n }\n}\n\n/** Parse Schema::table calls (alter). */\nfunction extractSchemaTable(\n source: string,\n timestamp: string | undefined,\n migrations: RawMigration[],\n): void {\n const regex = /Schema::table\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*,\\s*function\\s*\\([^)]*\\)\\s*\\{([\\s\\S]*?)\\}\\s*\\)/g;\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const tableName = match[1];\n const body = match[2];\n const columns = extractColumns(body);\n\n migrations.push({\n tableName,\n operation: 'alter',\n columns,\n timestamp,\n });\n }\n}\n\n/** Parse Schema::drop and Schema::dropIfExists calls. */\nfunction extractSchemaDrop(\n source: string,\n timestamp: string | undefined,\n migrations: RawMigration[],\n): void {\n const regex = /Schema::(?:drop|dropIfExists)\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n migrations.push({\n tableName: match[1],\n operation: 'drop',\n timestamp,\n });\n }\n}\n\n/** Extract column definitions from a migration body. */\nfunction extractColumns(body: string): Record<string, unknown>[] {\n const columns: Record<string, unknown>[] = [];\n const methodNames = Object.keys(COLUMN_TYPES).join('|');\n\n // Match: $table->string('name'), $table->id(), $table->timestamps(), etc.\n const regex = new RegExp(\n `\\\\$table->(${methodNames})\\\\s*\\\\(\\\\s*(?:['\"]([^'\"]*)['\"'])?[^)]*\\\\)([^;]*);`,\n 'g',\n );\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(body)) !== null) {\n const method = match[1];\n const columnName = match[2];\n const chain = match[3] ?? '';\n const type = COLUMN_TYPES[method] ?? method;\n\n // Special methods that don't have a column name (timestamps, softDeletes, etc.)\n if (!columnName && (method === 'timestamps' || method === 'nullableTimestamps')) {\n columns.push({ name: 'created_at', type: 'timestamp', nullable: true });\n columns.push({ name: 'updated_at', type: 'timestamp', nullable: true });\n continue;\n }\n\n if (!columnName && method === 'softDeletes') {\n columns.push({ name: 'deleted_at', type: 'timestamp', nullable: true });\n continue;\n }\n\n if (!columnName && method === 'rememberToken') {\n columns.push({ name: 'remember_token', type: 'varchar', nullable: true });\n continue;\n }\n\n if (!columnName && method === 'id') {\n columns.push({ name: 'id', type: 'bigint', autoIncrement: true, primary: true });\n continue;\n }\n\n if (!columnName) continue;\n\n const col: Record<string, unknown> = { name: columnName, type };\n if (chain.includes('->nullable()')) col.nullable = true;\n if (chain.includes('->unique()')) col.unique = true;\n if (chain.includes('->constrained()')) col.foreign = true;\n\n const defaultMatch = chain.match(/->default\\s*\\(\\s*['\"]?([^'\")\\s]+)['\"]?\\s*\\)/);\n if (defaultMatch) col.default = defaultMatch[1];\n\n columns.push(col);\n }\n\n return columns;\n}\n","/**\n * Laravel FormRequest detection and rule extraction.\n * Detects classes extending FormRequest and extracts validation rules.\n */\n\nexport interface FormRequestInfo {\n className: string;\n namespace: string | undefined;\n fqn: string;\n rules: Record<string, string>;\n}\n\n/**\n * Check if a PHP source file contains a FormRequest class.\n * Returns the form request info if found, null otherwise.\n */\nexport function extractFormRequest(source: string): FormRequestInfo | null {\n // Check for FormRequest extends\n const classMatch = source.match(\n /class\\s+(\\w+)\\s+extends\\s+(?:\\\\?(?:Illuminate\\\\Foundation\\\\Http\\\\)?)?FormRequest\\b/,\n );\n if (!classMatch) return null;\n\n const className = classMatch[1];\n const namespace = extractNamespace(source);\n const fqn = namespace ? `${namespace}\\\\${className}` : className;\n\n return {\n className,\n namespace,\n fqn,\n rules: extractRules(source),\n };\n}\n\n/** Extract namespace from source. */\nfunction extractNamespace(source: string): string | undefined {\n const match = source.match(/namespace\\s+([\\w\\\\]+)\\s*;/);\n return match ? match[1] : undefined;\n}\n\n/** Extract the rules() method return array. */\nfunction extractRules(source: string): Record<string, string> {\n const rules: Record<string, string> = {};\n\n // Match rules() method body\n const methodMatch = source.match(\n /function\\s+rules\\s*\\(\\s*\\)(?:\\s*:\\s*array)?\\s*\\{([\\s\\S]*?)\\breturn\\s*\\[([\\s\\S]*?)\\]\\s*;/,\n );\n if (!methodMatch) return rules;\n\n const body = methodMatch[2];\n const regex = /['\"]([^'\"]+)['\"]\\s*=>\\s*['\"]([^'\"]+)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(body)) !== null) {\n rules[match[1]] = match[2];\n }\n\n return rules;\n}\n\n/**\n * Detect FormRequest type-hints in controller method parameters.\n * Returns an array of { methodName, requestFqn } pairs.\n */\nexport function detectFormRequestUsage(\n source: string,\n): { methodName: string; requestClass: string }[] {\n const results: { methodName: string; requestClass: string }[] = [];\n const useMap = buildUseMap(source);\n\n // Match: public function store(StoreUserRequest $request)\n const regex = /public\\s+function\\s+(\\w+)\\s*\\(\\s*(\\w+)\\s+\\$\\w+/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const methodName = match[1];\n const typeHint = match[2];\n\n // Resolve to FQN if it's in use map\n const fqn = useMap.get(typeHint) ?? typeHint;\n\n // Only include if it looks like a Request class\n if (typeHint.endsWith('Request') || fqn.includes('Request')) {\n results.push({ methodName, requestClass: fqn });\n }\n }\n\n return results;\n}\n\n/** Build a map of short class name -> FQN from use statements. */\nfunction buildUseMap(source: string): Map<string, string> {\n const map = new Map<string, string>();\n const regex = /use\\s+([\\w\\\\]+?)(?:\\s+as\\s+(\\w+))?;/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const fqn = match[1];\n const alias = match[2] ?? fqn.split('\\\\').pop()!;\n map.set(alias, fqn);\n }\n return map;\n}\n","/**\n * Laravel Event/Listener graph extraction.\n * Parses EventServiceProvider $listen property and event()/dispatch() calls.\n */\nimport type { RawEdge } from '../../../../plugin-api/types.js';\n\nexport interface EventListenerMapping {\n eventClass: string;\n listenerClasses: string[];\n}\n\nexport interface EventDispatch {\n eventClass: string;\n location: string; // 'ClassName::methodName' or similar\n}\n\n/**\n * Extract $listen mappings from an EventServiceProvider source.\n * Returns Event -> Listener[] pairs.\n */\nexport function extractEventListeners(\n source: string,\n): EventListenerMapping[] {\n const mappings: EventListenerMapping[] = [];\n const useMap = buildUseMap(source);\n\n // Match: protected $listen = [ EventClass::class => [ ListenerClass::class, ... ], ... ];\n const listenMatch = source.match(\n /\\$listen\\s*=\\s*\\[([\\s\\S]*?)\\]\\s*;/,\n );\n if (!listenMatch) return mappings;\n\n const body = listenMatch[1];\n\n // Match each event => listeners pair\n const pairRegex = /([\\w\\\\]+)::class\\s*=>\\s*\\[([\\s\\S]*?)\\]/g;\n let match: RegExpExecArray | null;\n while ((match = pairRegex.exec(body)) !== null) {\n const eventRef = match[1];\n const listenersBlock = match[2];\n\n const eventClass = resolveClass(eventRef, useMap);\n const listenerClasses: string[] = [];\n\n const listenerRegex = /([\\w\\\\]+)::class/g;\n let lm: RegExpExecArray | null;\n while ((lm = listenerRegex.exec(listenersBlock)) !== null) {\n listenerClasses.push(resolveClass(lm[1], useMap));\n }\n\n mappings.push({ eventClass, listenerClasses });\n }\n\n return mappings;\n}\n\n/**\n * Detect event() and dispatch() calls in a source file.\n * Returns a list of dispatched event class references.\n */\nexport function detectEventDispatches(\n source: string,\n): string[] {\n const useMap = buildUseMap(source);\n const dispatches: string[] = [];\n\n // Match: event(new EventClass(...))\n const eventRegex = /\\bevent\\s*\\(\\s*new\\s+(\\w+)\\s*\\(/g;\n let match: RegExpExecArray | null;\n while ((match = eventRegex.exec(source)) !== null) {\n dispatches.push(resolveClass(match[1], useMap));\n }\n\n // Match: EventClass::dispatch(...)\n const dispatchRegex = /(\\w+)::dispatch\\s*\\(/g;\n while ((match = dispatchRegex.exec(source)) !== null) {\n const cls = match[1];\n // Skip Route::dispatch, etc.\n if (['Route', 'Bus', 'Queue'].includes(cls)) continue;\n dispatches.push(resolveClass(cls, useMap));\n }\n\n return dispatches;\n}\n\n/**\n * Build listens_to edges from event-listener mappings.\n */\nexport function buildEventEdges(\n mappings: EventListenerMapping[],\n): RawEdge[] {\n const edges: RawEdge[] = [];\n\n for (const mapping of mappings) {\n for (const listener of mapping.listenerClasses) {\n edges.push({\n edgeType: 'listens_to',\n metadata: {\n sourceFqn: listener,\n targetFqn: mapping.eventClass,\n },\n });\n }\n }\n\n return edges;\n}\n\n/**\n * Build dispatches edges from detected event dispatches.\n */\nexport function buildDispatchEdges(\n sourceFqn: string,\n dispatches: string[],\n): RawEdge[] {\n return dispatches.map((eventClass) => ({\n edgeType: 'dispatches',\n metadata: {\n sourceFqn,\n targetFqn: eventClass,\n },\n }));\n}\n\n/** Build a map of short class name -> FQN from use statements. */\nfunction buildUseMap(source: string): Map<string, string> {\n const map = new Map<string, string>();\n const regex = /use\\s+([\\w\\\\]+?)(?:\\s+as\\s+(\\w+))?;/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const fqn = match[1];\n const alias = match[2] ?? fqn.split('\\\\').pop()!;\n map.set(alias, fqn);\n }\n return map;\n}\n\n/** Resolve a short class name to FQN using use map. */\nfunction resolveClass(ref: string, useMap: Map<string, string>): string {\n if (ref.includes('\\\\')) return ref;\n return useMap.get(ref) ?? ref;\n}\n","/**\n * Livewire component extraction — supports v2 and v3.\n *\n * Extracts:\n * - Component class → Blade view (explicit render() or convention)\n * - Event dispatch/listen graph (v2: emit/$listeners, v3: dispatch/#[On])\n * - Form objects (v3 only)\n * - Public properties (reactive state) and methods (callable actions)\n * - Blade-side: <livewire:name/>, @livewire(), wire:click directives\n */\nimport type { RawEdge } from '../../../../plugin-api/types.js';\n\n// ─── Interfaces ──────────────────────────────────────────────\n\nexport interface LivewireComponentInfo {\n className: string;\n namespace: string;\n fqn: string;\n /** Explicit view name from render() method, e.g. 'livewire.counter' */\n viewName: string | null;\n /** Convention-based view path (always computed) */\n conventionViewPath: string;\n properties: LivewireProperty[];\n actions: string[];\n dispatches: LivewireEventRef[];\n listeners: LivewireListenerRef[];\n formProperty: LivewireFormRef | null;\n version: 2 | 3;\n}\n\nexport interface LivewireProperty {\n name: string;\n type: string | null;\n hasUrlAttribute: boolean;\n hasValidateAttribute: boolean;\n hasLockedAttribute: boolean;\n hasComputedAttribute: boolean;\n}\n\nexport interface LivewireEventRef {\n eventName: string;\n method: string; // which method dispatches it\n}\n\nexport interface LivewireListenerRef {\n eventName: string;\n handlerMethod: string;\n}\n\nexport interface LivewireFormRef {\n propertyName: string;\n formClass: string;\n}\n\nexport interface LivewireBladeUsage {\n componentName: string; // kebab-case: 'order-form'\n line: number;\n syntax: 'tag' | 'directive'; // <livewire:x/> vs @livewire('x')\n}\n\nexport interface LivewireWireDirective {\n directive: string; // 'click', 'submit', 'model'\n value: string; // method name or property name\n line: number;\n}\n\n// ─── PHP-side extraction ─────────────────────────────────────\n\nconst USE_STMT_RE = /use\\s+([\\w\\\\]+?)(?:\\s+as\\s+(\\w+))?;/g;\nconst NAMESPACE_RE = /namespace\\s+([\\w\\\\]+)\\s*;/;\nconst CLASS_DECL_RE = /class\\s+(\\w+)\\s+extends\\s+([\\w\\\\]+)/;\n\n/** Check if class extends Livewire\\Component (v3) or Livewire\\Component (v2). */\nconst LIVEWIRE_EXTENDS_RE = /class\\s+(\\w+)\\s+extends\\s+(?:[\\w\\\\]*\\\\)?Component\\b/;\n\n/** v3: #[On('event-name')] */\nconst ON_ATTRIBUTE_RE = /#\\[On\\(\\s*['\"]([\\w.:*-]+)['\"]\\s*\\)\\]/g;\n\n/** v3: $this->dispatch('event-name') */\nconst DISPATCH_RE = /\\$this->dispatch\\(\\s*['\"]([\\w.:*-]+)['\"]/g;\n\n/** v2: $this->emit('eventName') / $this->emitTo('component', 'event') / $this->emitUp('event') */\nconst EMIT_RE = /\\$this->emit(?:To|Up|Self)?\\(\\s*(?:['\"][\\w.-]+['\"]\\s*,\\s*)?['\"]([\\w.-]+)['\"]/g;\n\n/** v2: protected $listeners = ['eventName' => 'handlerMethod', ...] */\nconst LISTENERS_PROP_RE = /protected\\s+\\$listeners\\s*=\\s*\\[([\\s\\S]*?)\\]\\s*;/;\n\n/** render() method returning view('livewire.xxx') */\nconst RENDER_VIEW_RE = /function\\s+render\\s*\\([\\s\\S]*?\\)\\s*(?::\\s*[\\w\\\\|]+\\s*)?\\{[\\s\\S]*?view\\(\\s*['\"]([\\w.-]+)['\"]\\s*\\)/;\n\n/** Public method detection (callable actions) — excludes lifecycle hooks */\nconst PUBLIC_METHOD_RE = /public\\s+function\\s+(\\w+)\\s*\\(/g;\nconst LIFECYCLE_METHODS = new Set([\n 'mount', 'hydrate', 'dehydrate', 'render', 'updating', 'updated',\n 'boot', 'booted', '__construct',\n // v2 computed getter pattern\n]);\n\n/** Public property detection */\nconst PUBLIC_PROP_RE = /(?:#\\[([\\w,\\s()'\":]+)\\]\\s*)*public\\s+(?:(?:readonly\\s+)?(\\?\\s*)?(\\w[\\w\\\\|]*)\\s+)?\\$(\\w+)/g;\n\n/** v3 #[Computed] attribute */\nconst COMPUTED_ATTR_RE = /#\\[Computed(?:\\(.*?\\))?\\]/;\n/** v3 #[Url] attribute */\nconst URL_ATTR_RE = /#\\[Url(?:\\(.*?\\))?\\]/;\n/** v3 #[Validate(...)] attribute */\nconst VALIDATE_ATTR_RE = /#\\[Validate\\(/;\n/** v3 #[Locked] attribute */\nconst LOCKED_ATTR_RE = /#\\[Locked(?:\\(.*?\\))?\\]/;\n\n/** v3: Form class typed property — public PostForm $form */\nconst FORM_EXTENDS_RE = /class\\s+\\w+\\s+extends\\s+(?:[\\w\\\\]*\\\\)?Form\\b/;\n\n/**\n * Extract Livewire component metadata from a PHP source file.\n * Returns null if the file does not contain a Livewire component.\n */\nexport function extractLivewireComponent(\n source: string,\n filePath: string,\n): LivewireComponentInfo | null {\n if (!LIVEWIRE_EXTENDS_RE.test(source)) return null;\n\n const useMap = buildUseMap(source);\n const nsMatch = source.match(NAMESPACE_RE);\n const namespace = nsMatch?.[1] ?? '';\n const classMatch = source.match(CLASS_DECL_RE);\n if (!classMatch) return null;\n\n const className = classMatch[1];\n const fqn = namespace ? `${namespace}\\\\${className}` : className;\n\n // Detect version by namespace or API usage\n const version = detectVersion(source, namespace);\n\n // View resolution\n const viewMatch = source.match(RENDER_VIEW_RE);\n const viewName = viewMatch?.[1] ?? null;\n const conventionViewPath = classToConventionView(fqn, version);\n\n // Properties (resolve short type names through use map)\n const properties = extractProperties(source);\n for (const prop of properties) {\n if (prop.type && !prop.type.includes('\\\\')) {\n prop.type = resolveClass(prop.type, useMap);\n }\n }\n\n // Actions (public methods minus lifecycle)\n const actions = extractActions(source);\n\n // Events\n const dispatches = extractDispatches(source, version);\n const listeners = extractListeners(source, version);\n\n // Form (v3)\n const formProperty = extractFormProperty(source, useMap);\n\n return {\n className,\n namespace,\n fqn,\n viewName,\n conventionViewPath,\n properties,\n actions,\n dispatches,\n listeners,\n formProperty,\n version,\n };\n}\n\n/**\n * Detect if a PHP source is a Livewire Form class (v3).\n */\nexport function isLivewireForm(source: string): boolean {\n return FORM_EXTENDS_RE.test(source);\n}\n\n/**\n * Extract Livewire component usages from a Blade template.\n * Detects <livewire:name /> and @livewire('name') syntax.\n */\nexport function extractLivewireBladeUsages(source: string): LivewireBladeUsage[] {\n const usages: LivewireBladeUsage[] = [];\n\n // <livewire:component-name /> or <livewire:component-name>\n const tagRe = /<livewire:([\\w.-]+)/g;\n let match: RegExpExecArray | null;\n while ((match = tagRe.exec(source)) !== null) {\n usages.push({\n componentName: match[1],\n line: lineAt(source, match.index),\n syntax: 'tag',\n });\n }\n\n // @livewire('component-name')\n const directiveRe = /@livewire\\(\\s*['\"]([\\w.-]+)['\"]/g;\n while ((match = directiveRe.exec(source)) !== null) {\n usages.push({\n componentName: match[1],\n line: lineAt(source, match.index),\n syntax: 'directive',\n });\n }\n\n return usages;\n}\n\n/**\n * Extract wire: directives from a Blade template.\n * Returns wire:click, wire:submit actions (not wire:model — those are informational).\n */\nexport function extractWireDirectives(source: string): LivewireWireDirective[] {\n const directives: LivewireWireDirective[] = [];\n\n // wire:click=\"methodName\" or wire:click.prevent=\"methodName\"\n // wire:submit=\"methodName\" or wire:submit.prevent=\"methodName\"\n // Value may contain blade interpolations: refreshList({{ $id }})\n const wireRe = /wire:(click|submit)(?:\\.\\w+)*\\s*=\\s*['\"]([^'\"]+)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = wireRe.exec(source)) !== null) {\n let value = match[2].trim();\n // Strip arguments including blade interpolations: \"refreshList({{ $id }})\" -> \"refreshList\"\n value = value.replace(/\\(.*$/s, '');\n directives.push({\n directive: match[1],\n value,\n line: lineAt(source, match.index),\n });\n }\n\n // wire:model is informational — include it for completeness\n const modelRe = /wire:model(?:\\.\\w+)*\\s*=\\s*['\"]([\\w.]+)['\"]/g;\n while ((match = modelRe.exec(source)) !== null) {\n directives.push({\n directive: 'model',\n value: match[1],\n line: lineAt(source, match.index),\n });\n }\n\n return directives;\n}\n\n/**\n * Build edges from Livewire component info.\n * Creates livewire_renders, livewire_dispatches, livewire_listens edges.\n */\nexport function buildLivewireEdges(\n component: LivewireComponentInfo,\n): RawEdge[] {\n const edges: RawEdge[] = [];\n\n // Component → View (livewire_renders)\n const viewPath = component.viewName\n ? `resources/views/${component.viewName.replace(/\\./g, '/')}.blade.php`\n : component.conventionViewPath;\n\n edges.push({\n edgeType: 'livewire_renders',\n metadata: {\n sourceFqn: component.fqn,\n targetViewPath: viewPath,\n viewName: component.viewName,\n convention: !component.viewName,\n },\n });\n\n // Dispatches\n for (const dispatch of component.dispatches) {\n edges.push({\n edgeType: 'livewire_dispatches',\n metadata: {\n sourceFqn: component.fqn,\n eventName: dispatch.eventName,\n method: dispatch.method,\n },\n });\n }\n\n // Listeners\n for (const listener of component.listeners) {\n edges.push({\n edgeType: 'livewire_listens',\n metadata: {\n sourceFqn: component.fqn,\n eventName: listener.eventName,\n handlerMethod: listener.handlerMethod,\n },\n });\n }\n\n // Form (v3)\n if (component.formProperty) {\n edges.push({\n edgeType: 'livewire_form',\n metadata: {\n sourceFqn: component.fqn,\n targetFqn: component.formProperty.formClass,\n propertyName: component.formProperty.propertyName,\n },\n });\n }\n\n // Model references from typed properties\n for (const prop of component.properties) {\n if (prop.type && isEloquentLikeType(prop.type)) {\n edges.push({\n edgeType: 'livewire_uses_model',\n metadata: {\n sourceFqn: component.fqn,\n targetFqn: prop.type,\n propertyName: prop.name,\n },\n });\n }\n }\n\n return edges;\n}\n\n/**\n * Resolve a kebab-case component name to a class FQN.\n * 'order-form' → 'App\\Livewire\\OrderForm' (v3) or 'App\\Http\\Livewire\\OrderForm' (v2)\n */\nexport function resolveComponentName(\n name: string,\n version: 2 | 3,\n): string {\n // kebab-case → PascalCase: 'order-form' → 'OrderForm'\n const pascal = name\n .split(/[.-]/)\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\n .join('');\n\n return version === 3\n ? `App\\\\Livewire\\\\${pascal}`\n : `App\\\\Http\\\\Livewire\\\\${pascal}`;\n}\n\n// ─── Internal helpers ────────────────────────────────────────\n\nfunction buildUseMap(source: string): Map<string, string> {\n const map = new Map<string, string>();\n const regex = new RegExp(USE_STMT_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const fqn = match[1];\n const alias = match[2] ?? fqn.split('\\\\').pop()!;\n map.set(alias, fqn);\n }\n return map;\n}\n\nfunction resolveClass(ref: string, useMap: Map<string, string>): string {\n if (ref.includes('\\\\')) return ref;\n return useMap.get(ref) ?? ref;\n}\n\nfunction detectVersion(source: string, namespace: string): 2 | 3 {\n // v3 namespace pattern\n if (namespace.startsWith('App\\\\Livewire')) return 3;\n // v2 namespace pattern\n if (namespace.startsWith('App\\\\Http\\\\Livewire')) return 2;\n // v3 attributes\n if (/#\\[On\\(/.test(source) || /#\\[Computed\\]/.test(source) || /#\\[Url\\]/.test(source)) return 3;\n // v3 dispatch\n if (/\\$this->dispatch\\(/.test(source)) return 3;\n // v2 emit\n if (/\\$this->emit\\(/.test(source)) return 2;\n // v2 $listeners\n if (/protected\\s+\\$listeners/.test(source)) return 2;\n // Default to v3 (more recent)\n return 3;\n}\n\nfunction classToConventionView(fqn: string, version: 2 | 3): string {\n // Strip base namespace: App\\Livewire\\OrderForm → OrderForm\n // App\\Http\\Livewire\\OrderForm → OrderForm\n // App\\Livewire\\Admin\\UserList → Admin\\UserList\n const prefix = version === 3 ? 'App\\\\Livewire\\\\' : 'App\\\\Http\\\\Livewire\\\\';\n let relative = fqn.startsWith(prefix) ? fqn.slice(prefix.length) : fqn;\n\n // PascalCase → kebab-case: 'OrderForm' → 'order-form'\n // 'Admin\\UserList' → 'admin/user-list'\n relative = relative\n .replace(/\\\\/g, '/')\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .toLowerCase();\n\n return `resources/views/livewire/${relative}.blade.php`;\n}\n\nfunction extractProperties(source: string): LivewireProperty[] {\n const properties: LivewireProperty[] = [];\n const regex = new RegExp(PUBLIC_PROP_RE.source, 'g');\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(source)) !== null) {\n const attrs = match[1] ?? '';\n const type = match[3] ?? null;\n const name = match[4];\n\n // Skip properties that look like framework internals\n if (name.startsWith('_')) continue;\n\n properties.push({\n name,\n type,\n hasUrlAttribute: URL_ATTR_RE.test(attrs),\n hasValidateAttribute: VALIDATE_ATTR_RE.test(attrs),\n hasLockedAttribute: LOCKED_ATTR_RE.test(attrs),\n hasComputedAttribute: COMPUTED_ATTR_RE.test(attrs),\n });\n }\n\n return properties;\n}\n\nfunction extractActions(source: string): string[] {\n const actions: string[] = [];\n const regex = new RegExp(PUBLIC_METHOD_RE.source, 'g');\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(source)) !== null) {\n const name = match[1];\n if (!LIFECYCLE_METHODS.has(name) && !name.startsWith('get') && !name.endsWith('Property')) {\n actions.push(name);\n }\n }\n\n return actions;\n}\n\nfunction extractDispatches(source: string, version: 2 | 3): LivewireEventRef[] {\n const dispatches: LivewireEventRef[] = [];\n const re = version === 3 ? DISPATCH_RE : EMIT_RE;\n const regex = new RegExp(re.source, 'g');\n let match: RegExpExecArray | null;\n\n // Find which method each dispatch is in\n const methods = extractMethodBodies(source);\n\n while ((match = regex.exec(source)) !== null) {\n const eventName = match[1];\n const pos = match.index;\n const method = findEnclosingMethod(methods, pos) ?? 'unknown';\n dispatches.push({ eventName, method });\n }\n\n return dispatches;\n}\n\nfunction extractListeners(source: string, version: 2 | 3): LivewireListenerRef[] {\n const listeners: LivewireListenerRef[] = [];\n\n if (version === 3) {\n // #[On('event-name')] on methods\n const onRe = new RegExp(ON_ATTRIBUTE_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = onRe.exec(source)) !== null) {\n const eventName = match[1];\n // Next public function after this attribute\n const after = source.slice(match.index);\n const methodMatch = after.match(/function\\s+(\\w+)\\s*\\(/);\n if (methodMatch) {\n listeners.push({ eventName, handlerMethod: methodMatch[1] });\n }\n }\n } else {\n // v2: protected $listeners = ['eventName' => 'handlerMethod', 'eventName']\n const listenersMatch = source.match(LISTENERS_PROP_RE);\n if (listenersMatch) {\n const body = listenersMatch[1];\n // 'eventName' => 'handlerMethod'\n const pairRe = /['\"]([\\w.-]+)['\"]\\s*=>\\s*['\"]([\\w]+)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = pairRe.exec(body)) !== null) {\n listeners.push({ eventName: match[1], handlerMethod: match[2] });\n }\n // 'eventName' (shorthand — handler = same name)\n const shortRe = /(?<!=\\s*)\\s*['\"]([\\w.-]+)['\"]\\s*(?=[,\\]])/g;\n while ((match = shortRe.exec(body)) !== null) {\n // Avoid re-matching the key part of key => value pairs\n if (!body.slice(Math.max(0, match.index - 5), match.index).includes('=>')) {\n // Check if this is not the value side of a => pair\n const before = body.slice(0, match.index);\n if (!before.trimEnd().endsWith('=>')) {\n listeners.push({ eventName: match[1], handlerMethod: match[1] });\n }\n }\n }\n }\n }\n\n return listeners;\n}\n\nfunction extractFormProperty(\n source: string,\n useMap: Map<string, string>,\n): LivewireFormRef | null {\n // Look for typed public property whose type extends Form\n // Pattern: public SomeForm $form (or $propertyName)\n const formPropRe = /public\\s+(\\w+)\\s+\\$(\\w+)/g;\n let match: RegExpExecArray | null;\n\n while ((match = formPropRe.exec(source)) !== null) {\n const typeName = match[1];\n const propName = match[2];\n const resolvedType = resolveClass(typeName, useMap);\n\n // Heuristic: type name contains 'Form' (covers OrderFormData, PostForm, etc.)\n if (typeName.includes('Form') || resolvedType.includes('Form')) {\n return { propertyName: propName, formClass: resolvedType };\n }\n }\n\n return null;\n}\n\ninterface MethodRange {\n name: string;\n start: number;\n end: number;\n}\n\nfunction extractMethodBodies(source: string): MethodRange[] {\n const methods: MethodRange[] = [];\n const methodStartRe = /(?:public|protected|private)\\s+function\\s+(\\w+)\\s*\\([^)]*\\)[^{]*\\{/g;\n let match: RegExpExecArray | null;\n\n while ((match = methodStartRe.exec(source)) !== null) {\n const name = match[1];\n const start = match.index;\n const braceStart = source.indexOf('{', start + match[0].length - 1);\n const end = findMatchingBrace(source, braceStart);\n methods.push({ name, start, end });\n }\n\n return methods;\n}\n\nfunction findMatchingBrace(source: string, openPos: number): number {\n let depth = 0;\n for (let i = openPos; i < source.length; i++) {\n if (source[i] === '{') depth++;\n else if (source[i] === '}') {\n depth--;\n if (depth === 0) return i;\n }\n }\n return source.length;\n}\n\nfunction findEnclosingMethod(methods: MethodRange[], pos: number): string | null {\n for (const m of methods) {\n if (pos >= m.start && pos <= m.end) return m.name;\n }\n return null;\n}\n\nfunction lineAt(source: string, offset: number): number {\n return source.substring(0, offset).split('\\n').length;\n}\n\nfunction isEloquentLikeType(type: string): boolean {\n // Common model namespace patterns\n return /\\\\Models\\\\/.test(type) || /^App\\\\Models\\\\/.test(type);\n}\n","/**\n * Filament v3 extraction.\n *\n * Extracts:\n * - Resource → Eloquent Model ($model property)\n * - Resource → RelationManager[] (getRelations())\n * - RelationManager $relationship → Eloquent relation name\n * - form/table ->relationship() calls → related Model\n * - PanelProvider → registered Resources/Pages/Widgets\n * - Widget $model / getStats() model references\n * - getPages() → Page class array\n */\nimport type { RawEdge } from '../../../../plugin-api/types.js';\nimport { escapeRegExp } from '../../../../utils/security.js';\n\n// ─── Interfaces ──────────────────────────────────────────────\n\nexport interface FilamentResourceInfo {\n className: string;\n namespace: string;\n fqn: string;\n /** Eloquent model FQN from `protected static ?string $model = Model::class` */\n modelFqn: string | null;\n relationManagers: string[]; // FQNs\n pages: FilamentPageRef[];\n formRelationships: FilamentRelRef[];\n}\n\nexport interface FilamentPageRef {\n action: string; // 'index' | 'create' | 'edit' | 'view'\n pageClass: string;\n}\n\nexport interface FilamentRelRef {\n /** Relationship name string (e.g. 'role', 'posts') */\n relationName: string;\n}\n\nexport interface FilamentRelationManagerInfo {\n className: string;\n namespace: string;\n fqn: string;\n /** Value of `protected static string $relationship = 'posts'` */\n relationshipName: string | null;\n}\n\nexport interface FilamentPanelInfo {\n className: string;\n namespace: string;\n fqn: string;\n panelId: string | null;\n resources: string[]; // FQNs\n pages: string[];\n widgets: string[];\n}\n\nexport interface FilamentWidgetInfo {\n className: string;\n namespace: string;\n fqn: string;\n /** Static $model property on TableWidget / ChartWidget */\n modelFqn: string | null;\n /** Model FQNs referenced in getStats() / getColumns() */\n queriedModels: string[];\n}\n\n// ─── Detection helpers ────────────────────────────────────────\n\nconst NAMESPACE_RE = /namespace\\s+([\\w\\\\]+)\\s*;/;\nconst CLASS_NAME_RE = /class\\s+(\\w+)/;\nconst USE_STMT_RE = /use\\s+([\\w\\\\]+?)(?:\\s+as\\s+(\\w+))?;/g;\n\nconst EXTENDS_RESOURCE_RE = /class\\s+\\w+\\s+extends\\s+(?:[\\w\\\\]*\\\\)?Resource\\b/;\nconst EXTENDS_RELATION_MANAGER_RE = /class\\s+\\w+\\s+extends\\s+(?:[\\w\\\\]*\\\\)?RelationManager\\b/;\nconst EXTENDS_PANEL_PROVIDER_RE = /class\\s+\\w+\\s+extends\\s+(?:[\\w\\\\]*\\\\)?PanelProvider\\b/;\nconst EXTENDS_WIDGET_RE = /class\\s+\\w+\\s+extends\\s+(?:[\\w\\\\]*\\\\)?(?:StatsOverviewWidget|TableWidget|ChartWidget|Widget)\\b/;\n\n// ─── Resource extraction ──────────────────────────────────────\n\n/**\n * Extract Filament Resource metadata from a PHP source file.\n */\nexport function extractFilamentResource(\n source: string,\n _filePath: string,\n): FilamentResourceInfo | null {\n if (!EXTENDS_RESOURCE_RE.test(source)) return null;\n\n const useMap = buildUseMap(source);\n const nsMatch = source.match(NAMESPACE_RE);\n const namespace = nsMatch?.[1] ?? '';\n const classMatch = source.match(CLASS_NAME_RE);\n if (!classMatch) return null;\n const className = classMatch[1];\n const fqn = namespace ? `${namespace}\\\\${className}` : className;\n\n const modelFqn = extractModelProperty(source, useMap);\n const relationManagers = extractRelationManagers(source, useMap);\n const pages = extractPages(source, useMap);\n const formRelationships = extractFormRelationships(source);\n\n return { className, namespace, fqn, modelFqn, relationManagers, pages, formRelationships };\n}\n\n// ─── RelationManager extraction ───────────────────────────────\n\nexport function extractFilamentRelationManager(\n source: string,\n _filePath: string,\n): FilamentRelationManagerInfo | null {\n if (!EXTENDS_RELATION_MANAGER_RE.test(source)) return null;\n\n const nsMatch = source.match(NAMESPACE_RE);\n const namespace = nsMatch?.[1] ?? '';\n const classMatch = source.match(CLASS_NAME_RE);\n if (!classMatch) return null;\n const className = classMatch[1];\n const fqn = namespace ? `${namespace}\\\\${className}` : className;\n\n // protected static string $relationship = 'posts';\n const relMatch = source.match(\n /protected\\s+static\\s+(?:string\\s+)?\\$relationship\\s*=\\s*['\"](\\w+)['\"]/,\n );\n const relationshipName = relMatch?.[1] ?? null;\n\n return { className, namespace, fqn, relationshipName };\n}\n\n// ─── PanelProvider extraction ─────────────────────────────────\n\nexport function extractFilamentPanel(\n source: string,\n _filePath: string,\n): FilamentPanelInfo | null {\n if (!EXTENDS_PANEL_PROVIDER_RE.test(source)) return null;\n\n const useMap = buildUseMap(source);\n const nsMatch = source.match(NAMESPACE_RE);\n const namespace = nsMatch?.[1] ?? '';\n const classMatch = source.match(CLASS_NAME_RE);\n if (!classMatch) return null;\n const className = classMatch[1];\n const fqn = namespace ? `${namespace}\\\\${className}` : className;\n\n // ->id('admin')\n const idMatch = source.match(/->id\\(\\s*['\"](\\w+)['\"]\\s*\\)/);\n const panelId = idMatch?.[1] ?? null;\n\n const resources = extractClassList(source, 'resources', useMap);\n const pages = extractClassList(source, 'pages', useMap);\n const widgets = extractClassList(source, 'widgets', useMap);\n\n return { className, namespace, fqn, panelId, resources, pages, widgets };\n}\n\n// ─── Widget extraction ────────────────────────────────────────\n\nexport function extractFilamentWidget(\n source: string,\n _filePath: string,\n): FilamentWidgetInfo | null {\n if (!EXTENDS_WIDGET_RE.test(source)) return null;\n\n const useMap = buildUseMap(source);\n const nsMatch = source.match(NAMESPACE_RE);\n const namespace = nsMatch?.[1] ?? '';\n const classMatch = source.match(CLASS_NAME_RE);\n if (!classMatch) return null;\n const className = classMatch[1];\n const fqn = namespace ? `${namespace}\\\\${className}` : className;\n\n // Static $model on TableWidget / ChartWidget\n const modelFqn = extractModelProperty(source, useMap);\n\n // Models used in getStats() / getColumns() — Stat::make('X', Model::count())\n const queriedModels = extractQueriedModels(source, useMap);\n\n return { className, namespace, fqn, modelFqn, queriedModels };\n}\n\n// ─── Edge builders ────────────────────────────────────────────\n\nexport function buildFilamentResourceEdges(resource: FilamentResourceInfo): RawEdge[] {\n const edges: RawEdge[] = [];\n\n if (resource.modelFqn) {\n edges.push({\n edgeType: 'filament_resource_for',\n metadata: { sourceFqn: resource.fqn, targetFqn: resource.modelFqn },\n });\n }\n\n for (const rm of resource.relationManagers) {\n edges.push({\n edgeType: 'filament_relation_manager',\n metadata: { sourceFqn: resource.fqn, targetFqn: rm },\n });\n }\n\n for (const rel of resource.formRelationships) {\n edges.push({\n edgeType: 'filament_form_relationship',\n metadata: { sourceFqn: resource.fqn, relationName: rel.relationName },\n });\n }\n\n return edges;\n}\n\nexport function buildFilamentPanelEdges(panel: FilamentPanelInfo): RawEdge[] {\n const edges: RawEdge[] = [];\n for (const fqn of [...panel.resources, ...panel.pages, ...panel.widgets]) {\n edges.push({\n edgeType: 'filament_panel_registers',\n metadata: { sourceFqn: panel.fqn, targetFqn: fqn, panelId: panel.panelId },\n });\n }\n return edges;\n}\n\nexport function buildFilamentWidgetEdges(widget: FilamentWidgetInfo): RawEdge[] {\n const edges: RawEdge[] = [];\n const targets = [\n ...(widget.modelFqn ? [widget.modelFqn] : []),\n ...widget.queriedModels,\n ];\n for (const modelFqn of [...new Set(targets)]) {\n edges.push({\n edgeType: 'filament_widget_queries',\n metadata: { sourceFqn: widget.fqn, targetFqn: modelFqn },\n });\n }\n return edges;\n}\n\n// ─── Internal helpers ─────────────────────────────────────────\n\nfunction buildUseMap(source: string): Map<string, string> {\n const map = new Map<string, string>();\n const regex = new RegExp(USE_STMT_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const fqn = match[1];\n const alias = match[2] ?? fqn.split('\\\\').pop()!;\n map.set(alias, fqn);\n }\n return map;\n}\n\nfunction resolveClass(ref: string, useMap: Map<string, string>): string {\n if (ref.includes('\\\\')) return ref;\n return useMap.get(ref) ?? ref;\n}\n\n/** Extract `protected static ?string $model = SomeModel::class` */\nfunction extractModelProperty(source: string, useMap: Map<string, string>): string | null {\n const match = source.match(\n /protected\\s+static\\s+(?:\\?string\\s+)?\\$model\\s*=\\s*([\\w\\\\]+)::class/,\n );\n if (!match) return null;\n return resolveClass(match[1], useMap);\n}\n\n/** Extract getRelations() return array → array of RelationManager FQNs */\nfunction extractRelationManagers(source: string, useMap: Map<string, string>): string[] {\n const results: string[] = [];\n\n // Find getRelations() method body\n const methodMatch = source.match(/function\\s+getRelations\\s*\\([^)]*\\)[^{]*\\{([\\s\\S]*?)\\}/);\n if (!methodMatch) return results;\n\n const body = methodMatch[1];\n // Match: SomeRelationManager::class\n const classRe = /([\\w\\\\]+)::class/g;\n let match: RegExpExecArray | null;\n while ((match = classRe.exec(body)) !== null) {\n results.push(resolveClass(match[1], useMap));\n }\n return results;\n}\n\n/** Extract getPages() return array → array of page refs */\nfunction extractPages(source: string, useMap: Map<string, string>): FilamentPageRef[] {\n const results: FilamentPageRef[] = [];\n\n const methodMatch = source.match(/function\\s+getPages\\s*\\([^)]*\\)[^{]*\\{([\\s\\S]*?)\\}/);\n if (!methodMatch) return results;\n\n const body = methodMatch[1];\n // 'index' => Pages\\ListUsers::route('/'),\n const pairRe = /['\"](\\w+)['\"]\\s*=>\\s*([\\w\\\\]+)::route\\s*\\(/g;\n let match: RegExpExecArray | null;\n while ((match = pairRe.exec(body)) !== null) {\n results.push({\n action: match[1],\n pageClass: resolveClass(match[2], useMap),\n });\n }\n return results;\n}\n\n/** Extract ->relationship('name', ...) calls in form/table methods */\nfunction extractFormRelationships(source: string): FilamentRelRef[] {\n const results: FilamentRelRef[] = [];\n const re = /->relationship\\(\\s*['\"](\\w+)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n results.push({ relationName: match[1] });\n }\n // Deduplicate\n const seen = new Set<string>();\n return results.filter((r) => {\n if (seen.has(r.relationName)) return false;\n seen.add(r.relationName);\n return true;\n });\n}\n\n/** Extract array of class FQNs from ->resources([...]) / ->pages([...]) / ->widgets([...]) */\nfunction extractClassList(\n source: string,\n method: string,\n useMap: Map<string, string>,\n): string[] {\n const results: string[] = [];\n // ->resources([ ... ]) — allow multiline\n const methodRe = new RegExp(`->${escapeRegExp(method)}\\\\(\\\\s*\\\\[([\\\\s\\\\S]*?)\\\\]\\\\s*\\\\)`, 'g');\n let mMatch: RegExpExecArray | null;\n while ((mMatch = methodRe.exec(source)) !== null) {\n const block = mMatch[1];\n const classRe = /([\\w\\\\]+)::class/g;\n let match: RegExpExecArray | null;\n while ((match = classRe.exec(block)) !== null) {\n results.push(resolveClass(match[1], useMap));\n }\n }\n return results;\n}\n\n/** Extract Model FQNs used inside getStats() / getColumns() as Model::count(), Model::query(), etc. */\nfunction extractQueriedModels(source: string, useMap: Map<string, string>): string[] {\n const results: string[] = [];\n\n // Find getStats or getColumns method body\n const methodMatch = source.match(\n /function\\s+get(?:Stats|Columns|Data)\\s*\\([^)]*\\)[^{]*\\{([\\s\\S]*?)\\n\\s*\\}/,\n );\n if (!methodMatch) return results;\n\n const body = methodMatch[1];\n // Model::count(), Model::where(...), Model::query()\n const re = /([\\w\\\\]+)::\\s*(?:count|where|query|latest|all)\\s*\\(/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(body)) !== null) {\n const cls = match[1];\n if (['DB', 'Schema', 'Str', 'Carbon', 'Cache', 'Log'].includes(cls)) continue;\n results.push(resolveClass(cls, useMap));\n }\n\n return [...new Set(results)];\n}\n","/**\n * Laravel Nova extraction (v2–v5).\n *\n * Extracts:\n * - Resource → Eloquent Model ($model property)\n * - Relationship fields (BelongsTo/HasMany/HasOne/MorphMany/etc.) → target Nova Resource\n * - Actions, Filters, Lenses registered on Resource\n * - Metrics → queried Eloquent Model\n *\n * Version differences handled:\n * - v2–v3: single fields() method (flat array)\n * - v4–v5: fields() + fieldsForIndex/Detail/Create/Update + Panel::make([...fields...])\n */\nimport type { RawEdge } from '../../../../plugin-api/types.js';\nimport { escapeRegExp } from '../../../../utils/security.js';\n\n// ─── Interfaces ──────────────────────────────────────────────\n\nexport interface NovaResourceInfo {\n className: string;\n namespace: string;\n fqn: string;\n /** Eloquent model FQN from `public static $model = Model::class` */\n modelFqn: string | null;\n /** Nova relationship fields pointing to other Nova Resources */\n fieldRelationships: NovaFieldRelationship[];\n /** Action classes registered via actions() */\n actions: string[];\n /** Filter classes registered via filters() */\n filters: string[];\n /** Lens classes registered via lenses() */\n lenses: string[];\n /** Metric classes registered via cards() / metrics() */\n metrics: string[];\n}\n\nexport interface NovaFieldRelationship {\n /** Field type: BelongsTo, HasMany, HasOne, MorphMany, MorphTo, MorphToMany */\n fieldType: string;\n /** Label string */\n label: string;\n /** Attribute/relation name */\n attribute: string;\n /** Target Nova Resource FQN (third arg of ::make()) */\n targetResourceFqn: string;\n}\n\nexport interface NovaMetricInfo {\n className: string;\n namespace: string;\n fqn: string;\n /** Eloquent models queried in calculate() via $this->count/trend/partition(req, Model::class) */\n queriedModels: string[];\n}\n\n// ─── Relationship field types (stable v2→v5) ─────────────────\n\nconst RELATIONSHIP_FIELDS = new Set([\n 'BelongsTo', 'HasMany', 'HasOne', 'HasOneThrough', 'HasManyThrough',\n 'BelongsToMany', 'MorphTo', 'MorphMany', 'MorphOne', 'MorphToMany',\n]);\n\nconst METRIC_BASES = new Set(['Value', 'Trend', 'Partition', 'Progress']);\n\n// ─── Detection regexes ────────────────────────────────────────\n\nconst NAMESPACE_RE = /namespace\\s+([\\w\\\\]+)\\s*;/;\nconst CLASS_NAME_RE = /class\\s+(\\w+)/;\nconst USE_STMT_RE = /use\\s+([\\w\\\\]+?)(?:\\s+as\\s+(\\w+))?;/g;\n\nconst EXTENDS_RESOURCE_RE = /class\\s+\\w+\\s+extends\\s+(?:[\\w\\\\]*\\\\)?Resource\\b/;\nconst EXTENDS_ACTION_RE = /class\\s+\\w+\\s+extends\\s+(?:[\\w\\\\]*\\\\)?Action\\b/;\nconst EXTENDS_FILTER_RE = /class\\s+\\w+\\s+extends\\s+(?:[\\w\\\\]*\\\\)?Filter\\b/;\nconst EXTENDS_LENS_RE = /class\\s+\\w+\\s+extends\\s+(?:[\\w\\\\]*\\\\)?Lens\\b/;\nconst EXTENDS_METRIC_RE = new RegExp(\n `class\\\\s+\\\\w+\\\\s+extends\\\\s+(?:[\\\\w\\\\\\\\]*\\\\\\\\)?(?:${[...METRIC_BASES].join('|')})\\\\b`,\n);\n\n// ─── Resource extraction ──────────────────────────────────────\n\nexport function extractNovaResource(\n source: string,\n _filePath: string,\n): NovaResourceInfo | null {\n if (!EXTENDS_RESOURCE_RE.test(source)) return null;\n\n // Exclude Filament/Moonshine/Backpack resources that also extend Resource\n const parentMatch = source.match(/class\\s+\\w+\\s+extends\\s+([\\w\\\\]+)/);\n if (parentMatch && /Filament|Moonshine|Backpack/i.test(parentMatch[1])) return null;\n\n const useMap = buildUseMap(source);\n const nsMatch = source.match(NAMESPACE_RE);\n const namespace = nsMatch?.[1] ?? '';\n const classMatch = source.match(CLASS_NAME_RE);\n if (!classMatch) return null;\n const className = classMatch[1];\n const fqn = namespace ? `${namespace}\\\\${className}` : className;\n\n // $model property: public static $model = Model::class;\n const modelMatch = source.match(\n /public\\s+static\\s+\\$model\\s*=\\s*([\\w\\\\]+)::class/,\n );\n const modelFqn = modelMatch ? resolveClass(modelMatch[1], useMap) : null;\n\n // Collect all field method bodies (v2–v3: fields(), v4–v5: + fieldsFor*)\n const fieldBodies = collectFieldBodies(source);\n const fieldRelationships = extractFieldRelationships(fieldBodies, useMap);\n\n // actions() / filters() / lenses()\n const actions = extractRegisteredClasses(source, 'actions', useMap);\n const filters = extractRegisteredClasses(source, 'filters', useMap);\n const lenses = extractRegisteredClasses(source, 'lenses', useMap);\n\n // cards() / metrics() — both are used for metrics\n const metrics = [\n ...extractRegisteredClasses(source, 'cards', useMap),\n ...extractRegisteredClasses(source, 'metrics', useMap),\n ];\n\n return { className, namespace, fqn, modelFqn, fieldRelationships, actions, filters, lenses, metrics };\n}\n\n// ─── Metric extraction ────────────────────────────────────────\n\nexport function extractNovaMetric(\n source: string,\n _filePath: string,\n): NovaMetricInfo | null {\n if (!EXTENDS_METRIC_RE.test(source)) return null;\n\n const useMap = buildUseMap(source);\n const nsMatch = source.match(NAMESPACE_RE);\n const namespace = nsMatch?.[1] ?? '';\n const classMatch = source.match(CLASS_NAME_RE);\n if (!classMatch) return null;\n const className = classMatch[1];\n const fqn = namespace ? `${namespace}\\\\${className}` : className;\n\n // $this->count($request, Model::class) / $this->trend / $this->partition / $this->countByDays\n const queriedModels = extractMetricModels(source, useMap);\n\n return { className, namespace, fqn, queriedModels };\n}\n\n// ─── Edge builders ────────────────────────────────────────────\n\nexport function buildNovaResourceEdges(resource: NovaResourceInfo): RawEdge[] {\n const edges: RawEdge[] = [];\n\n if (resource.modelFqn) {\n edges.push({\n edgeType: 'nova_resource_for',\n metadata: { sourceFqn: resource.fqn, targetFqn: resource.modelFqn },\n });\n }\n\n for (const rel of resource.fieldRelationships) {\n edges.push({\n edgeType: 'nova_field_relationship',\n metadata: {\n sourceFqn: resource.fqn,\n targetFqn: rel.targetResourceFqn,\n fieldType: rel.fieldType,\n label: rel.label,\n attribute: rel.attribute,\n },\n });\n }\n\n for (const actionFqn of resource.actions) {\n edges.push({\n edgeType: 'nova_action_on',\n metadata: { sourceFqn: actionFqn, targetFqn: resource.fqn },\n });\n }\n\n for (const filterFqn of resource.filters) {\n edges.push({\n edgeType: 'nova_filter_on',\n metadata: { sourceFqn: filterFqn, targetFqn: resource.fqn },\n });\n }\n\n for (const lensFqn of resource.lenses) {\n edges.push({\n edgeType: 'nova_lens_on',\n metadata: { sourceFqn: lensFqn, targetFqn: resource.fqn },\n });\n }\n\n return edges;\n}\n\nexport function buildNovaMetricEdges(metric: NovaMetricInfo): RawEdge[] {\n return metric.queriedModels.map((modelFqn) => ({\n edgeType: 'nova_metric_queries',\n metadata: { sourceFqn: metric.fqn, targetFqn: modelFqn },\n }));\n}\n\n// ─── Internal helpers ─────────────────────────────────────────\n\nfunction buildUseMap(source: string): Map<string, string> {\n const map = new Map<string, string>();\n const re = new RegExp(USE_STMT_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const fqn = match[1];\n const alias = match[2] ?? fqn.split('\\\\').pop()!;\n map.set(alias, fqn);\n }\n return map;\n}\n\nfunction resolveClass(ref: string, useMap: Map<string, string>): string {\n const clean = ref.startsWith('\\\\') ? ref.slice(1) : ref;\n if (clean.includes('\\\\')) return clean;\n return useMap.get(clean) ?? clean;\n}\n\n/**\n * Collect the bodies of fields() and fieldsFor*() methods.\n * v4+: also handles Panel::make('label', [...fields...]) nesting.\n */\nfunction collectFieldBodies(source: string): string {\n const FIELD_METHODS = ['fields', 'fieldsForIndex', 'fieldsForDetail', 'fieldsForCreate', 'fieldsForUpdate'];\n const parts: string[] = [];\n\n for (const method of FIELD_METHODS) {\n const re = new RegExp(`function\\\\s+${escapeRegExp(method)}\\\\s*\\\\([^)]*\\\\)[^{]*\\\\{`, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const openBrace = source.indexOf('{', match.index + match[0].length - 1);\n const body = extractBraceBody(source, openBrace);\n parts.push(body);\n }\n }\n\n return parts.join('\\n');\n}\n\n/**\n * Extract relationship fields from collected field method bodies.\n * Pattern: BelongsTo::make('Label', 'attribute', ResourceClass::class)\n */\nfunction extractFieldRelationships(\n fieldBody: string,\n useMap: Map<string, string>,\n): NovaFieldRelationship[] {\n const results: NovaFieldRelationship[] = [];\n\n // Match: FieldType::make('Label', 'attribute', ResourceClass::class)\n // The third arg may be omitted (e.g. BelongsTo only needs resource class)\n const re = /(\\w+)::make\\(\\s*['\"]([^'\"]+)['\"]\\s*,\\s*['\"]?(\\w+)['\"]?\\s*,\\s*([\\w\\\\]+)::class/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(fieldBody)) !== null) {\n const fieldType = match[1];\n if (!RELATIONSHIP_FIELDS.has(fieldType)) continue;\n\n results.push({\n fieldType,\n label: match[2],\n attribute: match[3],\n targetResourceFqn: resolveClass(match[4], useMap),\n });\n }\n\n return results;\n}\n\n/**\n * Extract new ClassName() instances from a named method's return array.\n * Used for actions(), filters(), lenses(), cards(), metrics().\n */\nfunction extractRegisteredClasses(\n source: string,\n method: string,\n useMap: Map<string, string>,\n): string[] {\n const results: string[] = [];\n\n const methodRe = new RegExp(`function\\\\s+${escapeRegExp(method)}\\\\s*\\\\([^)]*\\\\)[^{]*\\\\{`, 'g');\n let mMatch: RegExpExecArray | null;\n while ((mMatch = methodRe.exec(source)) !== null) {\n const openBrace = source.indexOf('{', mMatch.index + mMatch[0].length - 1);\n const body = extractBraceBody(source, openBrace);\n\n // Match: new ClassName or new Namespace\\ClassName\n const newRe = /new\\s+([\\w\\\\]+)\\s*[,()\\]]/g;\n let match: RegExpExecArray | null;\n while ((match = newRe.exec(body)) !== null) {\n results.push(resolveClass(match[1], useMap));\n }\n\n // Also match ClassName::class in arrays\n const classRe = /([\\w\\\\]+)::class/g;\n while ((match = classRe.exec(body)) !== null) {\n const cls = match[1];\n if (!['static', 'self', 'parent'].includes(cls)) {\n results.push(resolveClass(cls, useMap));\n }\n }\n }\n\n // Deduplicate\n return [...new Set(results)];\n}\n\n/**\n * Extract Eloquent models referenced in calculate() via\n * $this->count($request, Model::class) etc.\n */\nfunction extractMetricModels(source: string, useMap: Map<string, string>): string[] {\n const results: string[] = [];\n\n const re = /\\$this->(?:count|trend|partition|countByDays|countByWeeks|countByMonths|sumByDays|averageByDays)\\s*\\([^,]+,\\s*([\\w\\\\]+)::class/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n results.push(resolveClass(match[1], useMap));\n }\n\n return [...new Set(results)];\n}\n\nfunction extractBraceBody(source: string, openPos: number): string {\n let depth = 0;\n let start = -1;\n for (let i = openPos; i < source.length; i++) {\n if (source[i] === '{') {\n depth++;\n if (depth === 1) start = i + 1;\n } else if (source[i] === '}') {\n depth--;\n if (depth === 0) return source.slice(start, i);\n }\n }\n return source.slice(start);\n}\n","/**\n * Laravel Broadcasting / Reverb extraction.\n *\n * Extends the event graph with:\n * - Events implementing ShouldBroadcast → broadcastOn() channel list\n * - broadcastAs() custom event name\n * - broadcastWith() payload field list\n * - routes/channels.php → Broadcast::channel() authorization callbacks\n */\nimport type { RawEdge } from '../../../../plugin-api/types.js';\n\n// ─── Interfaces ──────────────────────────────────────────────\n\nexport interface BroadcastingEventInfo {\n className: string;\n namespace: string;\n fqn: string;\n channels: BroadcastChannel[];\n /** Custom broadcast name from broadcastAs() */\n broadcastAs: string | null;\n /** Payload fields from broadcastWith() */\n payloadFields: string[];\n}\n\nexport interface BroadcastChannel {\n /** Channel name / pattern (may contain variables: 'orders.{userId}') */\n name: string;\n type: 'public' | 'private' | 'presence';\n}\n\nexport interface ChannelAuthMapping {\n /** Channel name pattern e.g. 'orders.{userId}' */\n pattern: string;\n /** FQN of authorization class, or 'closure' */\n authClass: string;\n}\n\n// ─── Detection ────────────────────────────────────────────────\n\nconst NAMESPACE_RE = /namespace\\s+([\\w\\\\]+)\\s*;/;\nconst CLASS_NAME_RE = /class\\s+(\\w+)/;\nconst USE_STMT_RE = /use\\s+([\\w\\\\]+?)(?:\\s+as\\s+(\\w+))?;/g;\n\nconst IMPLEMENTS_BROADCAST_RE =\n /class\\s+\\w+[^{]*implements[^{]*ShouldBroadcast(?:Now)?\\b/;\n\n// ─── Event extraction ─────────────────────────────────────────\n\nexport function extractBroadcastingEvent(\n source: string,\n _filePath: string,\n): BroadcastingEventInfo | null {\n if (!IMPLEMENTS_BROADCAST_RE.test(source)) return null;\n\n const useMap = buildUseMap(source);\n const nsMatch = source.match(NAMESPACE_RE);\n const namespace = nsMatch?.[1] ?? '';\n const classMatch = source.match(CLASS_NAME_RE);\n if (!classMatch) return null;\n const className = classMatch[1];\n const fqn = namespace ? `${namespace}\\\\${className}` : className;\n\n const channels = extractChannels(source, useMap);\n const broadcastAs = extractBroadcastAs(source);\n const payloadFields = extractPayloadFields(source);\n\n return { className, namespace, fqn, channels, broadcastAs, payloadFields };\n}\n\n// ─── Channel authorization extraction (routes/channels.php) ──\n\nexport function extractChannelAuthorizations(\n source: string,\n): ChannelAuthMapping[] {\n const results: ChannelAuthMapping[] = [];\n const useMap = buildUseMap(source);\n\n // Broadcast::channel('pattern', function(...) {...})\n // Broadcast::channel('pattern', ChannelClass::class)\n const re = /Broadcast::channel\\(\\s*['\"]([^'\"]+)['\"]\\s*,\\s*([^)]+)\\)/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const pattern = match[1];\n const handler = match[2].trim();\n\n let authClass: string;\n if (handler.startsWith('function') || handler.includes('=>')) {\n authClass = 'closure';\n } else {\n // ChannelClass::class or just ChannelClass\n const classMatch = handler.match(/([\\w\\\\]+)(?:::class)?/);\n authClass = classMatch ? resolveClass(classMatch[1], useMap) : 'closure';\n }\n\n results.push({ pattern, authClass });\n }\n\n return results;\n}\n\n// ─── Edge builders ────────────────────────────────────────────\n\nexport function buildBroadcastingEdges(event: BroadcastingEventInfo): RawEdge[] {\n const edges: RawEdge[] = [];\n\n for (const channel of event.channels) {\n edges.push({\n edgeType: 'broadcasts_on',\n metadata: {\n sourceFqn: event.fqn,\n channelName: channel.name,\n channelType: channel.type,\n broadcastAs: event.broadcastAs,\n payload: event.payloadFields,\n },\n });\n }\n\n return edges;\n}\n\nexport function buildChannelAuthEdges(mappings: ChannelAuthMapping[]): RawEdge[] {\n return mappings.map((m) => ({\n edgeType: 'broadcast_authorized_by',\n metadata: { channelPattern: m.pattern, authClass: m.authClass },\n }));\n}\n\n// ─── Internal helpers ─────────────────────────────────────────\n\nfunction buildUseMap(source: string): Map<string, string> {\n const map = new Map<string, string>();\n const re = new RegExp(USE_STMT_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const fqn = match[1];\n const alias = match[2] ?? fqn.split('\\\\').pop()!;\n map.set(alias, fqn);\n }\n return map;\n}\n\nfunction resolveClass(ref: string, useMap: Map<string, string>): string {\n const clean = ref.startsWith('\\\\') ? ref.slice(1) : ref;\n if (clean.includes('\\\\')) return clean;\n return useMap.get(clean) ?? clean;\n}\n\nfunction extractChannels(\n source: string,\n _useMap: Map<string, string>,\n): BroadcastChannel[] {\n const channels: BroadcastChannel[] = [];\n\n // Find broadcastOn() method body\n const methodMatch = source.match(\n /function\\s+broadcastOn\\s*\\([^)]*\\)[^{]*\\{([\\s\\S]*?)\\n\\s*\\}/,\n );\n if (!methodMatch) return channels;\n\n const body = methodMatch[1];\n\n // new PrivateChannel('name') / new Channel('name') / new PresenceChannel('name')\n const re = /new\\s+(Private|Presence)?Channel\\(\\s*['\"]([\\w.{}_-]+)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(body)) !== null) {\n const qualifier = match[1];\n const name = match[2];\n const type: BroadcastChannel['type'] =\n qualifier === 'Private' ? 'private'\n : qualifier === 'Presence' ? 'presence'\n : 'public';\n channels.push({ name, type });\n }\n\n // Also handle string concatenation: 'orders.' . $this->order->user_id\n // Extract just the base pattern\n const concatRe = /new\\s+(Private|Presence)?Channel\\(\\s*['\"]([^'\"]+)['\"]\\s*\\./g;\n while ((match = concatRe.exec(body)) !== null) {\n const qualifier = match[1];\n const baseName = match[2] + '{id}'; // simplified pattern\n const type: BroadcastChannel['type'] =\n qualifier === 'Private' ? 'private'\n : qualifier === 'Presence' ? 'presence'\n : 'public';\n // Only add if not already captured\n if (!channels.some((c) => c.name.startsWith(match![2]))) {\n channels.push({ name: baseName, type });\n }\n }\n\n return channels;\n}\n\nfunction extractBroadcastAs(source: string): string | null {\n const match = source.match(\n /function\\s+broadcastAs\\s*\\([^)]*\\)[^{]*\\{[^}]*return\\s*['\"]([^'\"]+)['\"]/,\n );\n return match?.[1] ?? null;\n}\n\nfunction extractPayloadFields(source: string): string[] {\n const fields: string[] = [];\n\n // broadcastWith() return ['field1' => ..., 'field2' => ...]\n const methodMatch = source.match(\n /function\\s+broadcastWith\\s*\\([^)]*\\)[^{]*\\{([\\s\\S]*?)\\n\\s*\\}/,\n );\n if (!methodMatch) return fields;\n\n const body = methodMatch[1];\n const re = /['\"](\\w+)['\"]\\s*=>/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(body)) !== null) {\n fields.push(match[1]);\n }\n\n return fields;\n}\n","/**\n * spatie/laravel-data extraction.\n *\n * Extracts:\n * - Data class constructor → typed field list\n * - Nested Data class properties → data_nests edges\n * - DataCollection<PostData> type hints → data_collects edges\n * - fromModel(Model $m) / ::from($model) → data_maps_from edges\n * - Inertia::render with Data objects → typed props (enriches InertiaPlugin)\n */\nimport type { RawEdge } from '../../../../plugin-api/types.js';\n\n// ─── Interfaces ──────────────────────────────────────────────\n\nexport interface DataClassInfo {\n className: string;\n namespace: string;\n fqn: string;\n /** Constructor promoted properties */\n fields: DataField[];\n /** Nested Data class FQNs from typed properties */\n nestedDataClasses: string[];\n /** Element Data class FQNs from DataCollection<T> */\n collectedDataClasses: string[];\n /** Eloquent model FQNs this DTO can be created from */\n sourceModels: string[];\n}\n\nexport interface DataField {\n name: string;\n type: string | null;\n nullable: boolean;\n mapFrom: string | null; // from #[MapFrom('...')]\n}\n\nexport interface InertiaDataProp {\n propKey: string;\n dataClass: string; // FQN of Data class\n isCollection: boolean;\n}\n\n// ─── Detection ────────────────────────────────────────────────\n\nconst NAMESPACE_RE = /namespace\\s+([\\w\\\\]+)\\s*;/;\nconst CLASS_NAME_RE = /class\\s+(\\w+)/;\nconst USE_STMT_RE = /use\\s+([\\w\\\\]+?)(?:\\s+as\\s+(\\w+))?;/g;\n\nconst EXTENDS_DATA_RE = /class\\s+\\w+\\s+extends\\s+(?:[\\w\\\\]*\\\\)?Data\\b/;\n\n// ─── Data class extraction ────────────────────────────────────\n\nexport function extractDataClass(\n source: string,\n _filePath: string,\n): DataClassInfo | null {\n if (!EXTENDS_DATA_RE.test(source)) return null;\n\n const useMap = buildUseMap(source);\n const nsMatch = source.match(NAMESPACE_RE);\n const namespace = nsMatch?.[1] ?? '';\n const classMatch = source.match(CLASS_NAME_RE);\n if (!classMatch) return null;\n const className = classMatch[1];\n const fqn = namespace ? `${namespace}\\\\${className}` : className;\n\n const PRIMITIVES = new Set(['string','int','float','bool','array','object','null','mixed','void','never','callable','iterable','self','static','parent']);\n const fields = extractConstructorFields(source, useMap);\n // Qualify any short type names that weren't resolved via use map (skip primitives)\n for (const f of fields) {\n if (f.type && !f.type.includes('\\\\') && !PRIMITIVES.has(f.type)) {\n f.type = qualifyWithNs(f.type, namespace);\n }\n }\n const nestedDataClasses = extractNestedDataClasses(fields, source, useMap, namespace);\n const collectedDataClasses = extractCollectedDataClasses(source, useMap, namespace);\n const sourceModels = extractSourceModels(source, useMap);\n\n return { className, namespace, fqn, fields, nestedDataClasses, collectedDataClasses, sourceModels };\n}\n\n/**\n * Detect Inertia::render() calls that pass Data objects as props.\n * Returns a map of prop key → Data class FQN.\n */\nexport function extractInertiaDataProps(source: string): InertiaDataProp[] {\n const results: InertiaDataProp[] = [];\n const useMap = buildUseMap(source);\n\n // Match Inertia::render('Page', [...]) or inertia('Page', [...])\n const renderRe = /(?:Inertia::render|inertia)\\(\\s*['\"][\\w/.-]+['\"]\\s*,\\s*\\[([\\s\\S]*?)\\]\\s*\\)/g;\n let rMatch: RegExpExecArray | null;\n while ((rMatch = renderRe.exec(source)) !== null) {\n const propsBlock = rMatch[1];\n\n // Look for: 'key' => DataClass::from(...) or DataClass::collect(...)\n const propRe = /['\"](\\w+)['\"]\\s*=>\\s*([\\w\\\\]+)::(from|collect)\\s*\\(/g;\n let pMatch: RegExpExecArray | null;\n while ((pMatch = propRe.exec(propsBlock)) !== null) {\n results.push({\n propKey: pMatch[1],\n dataClass: resolveClass(pMatch[2], useMap),\n isCollection: pMatch[3] === 'collect',\n });\n }\n }\n\n return results;\n}\n\n// ─── Edge builders ────────────────────────────────────────────\n\nexport function buildDataClassEdges(info: DataClassInfo): RawEdge[] {\n const edges: RawEdge[] = [];\n\n for (const nestedFqn of info.nestedDataClasses) {\n edges.push({\n edgeType: 'data_nests',\n metadata: { sourceFqn: info.fqn, targetFqn: nestedFqn },\n });\n }\n\n for (const collectedFqn of info.collectedDataClasses) {\n edges.push({\n edgeType: 'data_collects',\n metadata: { sourceFqn: info.fqn, targetFqn: collectedFqn },\n });\n }\n\n for (const modelFqn of info.sourceModels) {\n edges.push({\n edgeType: 'data_maps_from',\n metadata: { sourceFqn: info.fqn, targetFqn: modelFqn },\n });\n }\n\n return edges;\n}\n\n// ─── Internal helpers ─────────────────────────────────────────\n\nfunction buildUseMap(source: string): Map<string, string> {\n const map = new Map<string, string>();\n const re = new RegExp(USE_STMT_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const fqn = match[1];\n const alias = match[2] ?? fqn.split('\\\\').pop()!;\n map.set(alias, fqn);\n }\n return map;\n}\n\nfunction resolveClass(ref: string, useMap: Map<string, string>): string {\n const clean = ref.startsWith('\\\\') ? ref.slice(1) : ref;\n if (clean.includes('\\\\')) return clean;\n return useMap.get(clean) ?? clean;\n}\n\n/**\n * Extract promoted constructor properties (PHP 8 constructor promotion).\n * Handles: public string $name, public ?string $avatar = null,\n * #[MapFrom('created_at')] public CarbonImmutable $memberSince\n */\nfunction extractConstructorFields(\n source: string,\n useMap: Map<string, string>,\n): DataField[] {\n const fields: DataField[] = [];\n\n // Find constructor body\n const ctorMatch = source.match(\n /function\\s+__construct\\s*\\(([\\s\\S]*?)\\)\\s*(?::\\s*[\\w\\\\|]+\\s*)?\\{/,\n );\n if (!ctorMatch) return fields;\n\n const body = ctorMatch[1];\n\n // Match each promoted property (may have attributes above)\n // Pattern: optional #[...attrs...] then public [readonly] [?]Type $name [= default]\n const propRe = /(?:#\\[MapFrom\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)\\]\\s*)?public\\s+(?:readonly\\s+)?(\\??\\s*[\\w\\\\|]+)\\s+\\$(\\w+)/g;\n let match: RegExpExecArray | null;\n while ((match = propRe.exec(body)) !== null) {\n const mapFrom = match[1] ?? null;\n const typeRaw = match[2].trim();\n const name = match[3];\n const nullable = typeRaw.startsWith('?');\n const type = nullable ? typeRaw.slice(1).trim() : typeRaw;\n\n fields.push({\n name,\n type: resolveClass(type, useMap),\n nullable,\n mapFrom,\n });\n }\n\n return fields;\n}\n\n/**\n * Find typed properties that are themselves Data subclasses.\n * Uses heuristic: type is imported from a namespace containing 'Data'\n * OR type name ends with 'Data'.\n */\nfunction extractNestedDataClasses(\n fields: DataField[],\n source: string,\n _useMap: Map<string, string>,\n namespace: string,\n): string[] {\n const results: string[] = [];\n\n for (const field of fields) {\n if (!field.type) continue;\n // Skip primitives\n if (/^(string|int|float|bool|array|object|null|mixed|void|never)$/.test(field.type)) continue;\n // Skip DataCollection itself\n if (field.type.includes('DataCollection') || field.type.includes('Collection')) continue;\n // Heuristic: type name (short or FQN) ends with 'Data'\n const shortName = field.type.split('\\\\').pop() ?? '';\n if (shortName.endsWith('Data')) {\n results.push(field.type);\n }\n }\n\n // Also check class body for typed properties (non-constructor style)\n const useMap = buildUseMap(source);\n const propRe = /public\\s+(?:readonly\\s+)?([\\w\\\\]+Data)\\s+\\$\\w+/g;\n let match: RegExpExecArray | null;\n while ((match = propRe.exec(source)) !== null) {\n let resolved = resolveClass(match[1], useMap);\n if (!resolved.includes('\\\\')) resolved = qualifyWithNs(resolved, namespace);\n if (!results.includes(resolved)) results.push(resolved);\n }\n\n return [...new Set(results)];\n}\n\n/**\n * Extract DataCollection<ElementType> type hints.\n * Looks for: DataCollection $posts (with @var DataCollection<PostData>)\n * or: DataCollection<PostData> in docblocks.\n */\nfunction extractCollectedDataClasses(\n source: string,\n useMap: Map<string, string>,\n namespace: string,\n): string[] {\n const results: string[] = [];\n\n const qualify = (ref: string) => {\n let resolved = resolveClass(ref, useMap);\n if (!resolved.includes('\\\\')) resolved = qualifyWithNs(resolved, namespace);\n return resolved;\n };\n\n // DataCollection<PostData> anywhere in source\n const docRe = /DataCollection<([\\w\\\\]+)>/g;\n let match: RegExpExecArray | null;\n while ((match = docRe.exec(source)) !== null) {\n results.push(qualify(match[1]));\n }\n\n // @var DataCollection<PostData>\n const varRe = /@var\\s+DataCollection<([\\w\\\\]+)>/g;\n while ((match = varRe.exec(source)) !== null) {\n results.push(qualify(match[1]));\n }\n\n return [...new Set(results)];\n}\n\n/**\n * Detect Eloquent models this Data class can be constructed from.\n * Patterns:\n * - public static function fromModel(User $user): static\n * - ::from($model) where $model is typed as an Eloquent model\n * - Constructor with param typed as Eloquent model\n */\nfunction extractSourceModels(\n source: string,\n useMap: Map<string, string>,\n): string[] {\n const results: string[] = [];\n\n // Pattern 1: explicit fromModel(ModelType $param)\n const fromModelRe = /function\\s+from\\w*\\(\\s*([\\w\\\\]+)\\s+\\$\\w+/g;\n let match: RegExpExecArray | null;\n while ((match = fromModelRe.exec(source)) !== null) {\n const type = resolveClass(match[1], useMap);\n if (isEloquentLike(type, useMap)) {\n results.push(type);\n }\n }\n\n // Pattern 2: constructor promoted property typed as Eloquent model\n // Data::from($model) is convention-based — look for Model types in constructor\n const ctorMatch = source.match(/function\\s+__construct\\s*\\(([\\s\\S]*?)\\)\\s*(?::\\s*\\w+\\s*)?\\{/);\n if (ctorMatch) {\n const ctorBody = ctorMatch[1];\n const paramRe = /public\\s+(?:readonly\\s+)?(\\??\\s*[\\w\\\\]+)\\s+\\$\\w+/g;\n while ((match = paramRe.exec(ctorBody)) !== null) {\n const typeRaw = match[1].replace(/^\\?\\s*/, '').trim();\n const resolved = resolveClass(typeRaw, useMap);\n if (isEloquentLike(resolved, useMap)) {\n results.push(resolved);\n }\n }\n }\n\n return [...new Set(results)];\n}\n\nfunction isEloquentLike(fqn: string, _useMap: Map<string, string>): boolean {\n return /\\\\Models\\\\/.test(fqn) || /^App\\\\Models\\\\/.test(fqn);\n}\n\n/** Qualify a short unresolved name with the current namespace */\nfunction qualifyWithNs(shortName: string, namespace: string): string {\n if (!shortName || shortName.includes('\\\\')) return shortName;\n if (!namespace) return shortName;\n return `${namespace}\\\\${shortName}`;\n}\n","/**\n * Laravel Pennant feature flag extraction.\n *\n * Extracts:\n * - Feature::define('name', ...) → definition sites\n * - Feature::active('name') / Feature::when('name', ...) → usage sites\n * - @feature('name') Blade directive → blade usage\n * - Route middleware features:new-dashboard → route gate\n * - #[FeatureGate('name')] PHP 8 attribute → method gate\n */\nimport type { RawEdge } from '../../../../plugin-api/types.js';\n\n// ─── Interfaces ──────────────────────────────────────────────\n\nexport interface PennantFeatureDefinition {\n name: string;\n /** File + line where Feature::define() is called */\n location: string;\n line: number;\n}\n\nexport interface PennantFeatureUsage {\n name: string;\n usageType: 'active' | 'when' | 'value' | 'for' | 'blade' | 'middleware' | 'attribute';\n line: number;\n}\n\n// ─── Definition extraction ────────────────────────────────────\n\n/**\n * Extract Feature::define() calls from a PHP source file.\n */\nexport function extractFeatureDefinitions(\n source: string,\n filePath: string,\n): PennantFeatureDefinition[] {\n const definitions: PennantFeatureDefinition[] = [];\n\n // Feature::define('feature-name', function/class)\n const re = /Feature::define\\(\\s*['\"]([^'\"]+)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const line = lineAt(source, match.index);\n definitions.push({ name: match[1], location: filePath, line });\n }\n\n return definitions;\n}\n\n// ─── Usage extraction ─────────────────────────────────────────\n\n/**\n * Extract Feature::active/when/value/for() usages from a PHP source file.\n * Also detects #[FeatureGate('name')] attributes.\n */\nexport function extractFeatureUsages(source: string): PennantFeatureUsage[] {\n const usages: PennantFeatureUsage[] = [];\n\n // Feature::active('name'), Feature::inactive('name')\n const activeRe = /Feature::(?:active|inactive)\\(\\s*['\"]([^'\"]+)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = activeRe.exec(source)) !== null) {\n usages.push({ name: match[1], usageType: 'active', line: lineAt(source, match.index) });\n }\n\n // Feature::when('name', ...)\n const whenRe = /Feature::when\\(\\s*['\"]([^'\"]+)['\"]/g;\n while ((match = whenRe.exec(source)) !== null) {\n usages.push({ name: match[1], usageType: 'when', line: lineAt(source, match.index) });\n }\n\n // Feature::value('name')\n const valueRe = /Feature::value\\(\\s*['\"]([^'\"]+)['\"]/g;\n while ((match = valueRe.exec(source)) !== null) {\n usages.push({ name: match[1], usageType: 'value', line: lineAt(source, match.index) });\n }\n\n // Feature::for($user)->active('name')\n const forRe = /Feature::for\\(.*?\\)->(?:active|inactive|when|value)\\(\\s*['\"]([^'\"]+)['\"]/g;\n while ((match = forRe.exec(source)) !== null) {\n usages.push({ name: match[1], usageType: 'for', line: lineAt(source, match.index) });\n }\n\n // #[FeatureGate('name')]\n const attrRe = /#\\[FeatureGate\\(\\s*['\"]([^'\"]+)['\"]/g;\n while ((match = attrRe.exec(source)) !== null) {\n usages.push({ name: match[1], usageType: 'attribute', line: lineAt(source, match.index) });\n }\n\n return usages;\n}\n\n/**\n * Extract @feature('name') ... @endfeature from a Blade template.\n */\nexport function extractFeatureBladeUsages(source: string): PennantFeatureUsage[] {\n const usages: PennantFeatureUsage[] = [];\n\n const re = /@feature\\(\\s*['\"]([^'\"]+)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n usages.push({ name: match[1], usageType: 'blade', line: lineAt(source, match.index) });\n }\n\n return usages;\n}\n\n/**\n * Extract feature flag names from route middleware: features:name1,name2\n */\nexport function extractFeatureMiddlewareUsages(source: string): PennantFeatureUsage[] {\n const usages: PennantFeatureUsage[] = [];\n\n // ->middleware('features:flag-name') or ->middleware(['features:flag1', 'features:flag2'])\n const re = /['\"]features:([^'\"]+)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n // May be comma-separated: 'features:flag1,flag2'\n const flags = match[1].split(',');\n for (const flag of flags) {\n usages.push({ name: flag.trim(), usageType: 'middleware', line: lineAt(source, match.index) });\n }\n }\n\n return usages;\n}\n\n// ─── Edge builders ────────────────────────────────────────────\n\nexport function buildPennantEdges(\n definitions: PennantFeatureDefinition[],\n usages: PennantFeatureUsage[],\n filePath: string,\n): RawEdge[] {\n const edges: RawEdge[] = [];\n\n for (const def of definitions) {\n edges.push({\n edgeType: 'feature_defined_in',\n metadata: { featureName: def.name, filePath: def.location, line: def.line },\n });\n }\n\n for (const usage of usages) {\n edges.push({\n edgeType: 'feature_checked_by',\n metadata: {\n featureName: usage.name,\n filePath,\n line: usage.line,\n usageType: usage.usageType,\n },\n });\n }\n\n return edges;\n}\n\n// ─── Helper ───────────────────────────────────────────────────\n\nfunction lineAt(source: string, offset: number): number {\n return source.substring(0, offset).split('\\n').length;\n}\n","/**\n * Laravel middleware extraction.\n *\n * Supports two styles:\n * - Laravel 6–10: app/Http/Kernel.php ($middleware, $middlewareGroups, $routeMiddleware)\n * - Laravel 11+: bootstrap/app.php (->withMiddleware() callback with alias/web/api methods)\n */\n\nimport { escapeRegExp } from '../../../../utils/security.js';\n\nexport interface MiddlewareConfig {\n /** Global middleware applied to every request. */\n global: string[];\n\n /** Named middleware groups (e.g. 'web', 'api'). */\n groups: Record<string, string[]>;\n\n /** Route middleware aliases (e.g. 'auth' -> class FQN). */\n aliases: Record<string, string>;\n\n /** Source style: 'kernel' (L6-10) or 'bootstrap' (L11+). */\n source: 'kernel' | 'bootstrap';\n}\n\n/**\n * Parse middleware configuration from Kernel.php (Laravel 6–10).\n */\nexport function parseKernelMiddleware(source: string): MiddlewareConfig {\n return {\n global: extractPropertyArray(source, '$middleware'),\n groups: extractPropertyGroups(source, '$middlewareGroups'),\n aliases: {\n ...extractPropertyMap(source, '$routeMiddleware'),\n ...extractPropertyMap(source, '$middlewareAliases'), // L10+ alternative name\n },\n source: 'kernel',\n };\n}\n\n/**\n * Parse middleware configuration from bootstrap/app.php (Laravel 11+).\n */\nexport function parseBootstrapMiddleware(source: string): MiddlewareConfig {\n const config: MiddlewareConfig = {\n global: [],\n groups: {},\n aliases: {},\n source: 'bootstrap',\n };\n\n // Extract the withMiddleware callback body\n const mwBodyRegex = /->withMiddleware\\s*\\(\\s*function\\s*\\([^)]*\\)\\s*\\{([\\s\\S]*?)\\}\\s*\\)/;\n const bodyMatch = source.match(mwBodyRegex);\n if (!bodyMatch) return config;\n\n const body = bodyMatch[1];\n\n // Parse $middleware->alias([...])\n config.aliases = extractCallMap(body, 'alias');\n\n // Parse $middleware->web(append: [...]) and $middleware->api(prepend: [...])\n const webItems = extractCallArray(body, 'web');\n if (webItems.length > 0) {\n config.groups['web'] = webItems;\n }\n\n const apiItems = extractCallArray(body, 'api');\n if (apiItems.length > 0) {\n config.groups['api'] = apiItems;\n }\n\n return config;\n}\n\n/**\n * Extract a property that is a flat array of class references.\n * e.g. protected $middleware = [ \\App\\Http\\Middleware\\X::class, ... ];\n */\nfunction extractPropertyArray(source: string, propName: string): string[] {\n const escaped = escapeRegExp(propName);\n const regex = new RegExp(\n `protected\\\\s+${escaped}\\\\s*=\\\\s*\\\\[([\\\\s\\\\S]*?)\\\\];`,\n );\n const match = source.match(regex);\n if (!match) return [];\n return extractClassReferences(match[1]);\n}\n\n/**\n * Extract a property that is a map of group name -> array of class references.\n * e.g. protected $middlewareGroups = [ 'web' => [...], 'api' => [...] ];\n */\nfunction extractPropertyGroups(\n source: string,\n propName: string,\n): Record<string, string[]> {\n const escaped = escapeRegExp(propName);\n const regex = new RegExp(\n `protected\\\\s+${escaped}\\\\s*=\\\\s*\\\\[([\\\\s\\\\S]*?)\\\\];`,\n );\n const match = source.match(regex);\n if (!match) return {};\n\n const body = match[1];\n const groups: Record<string, string[]> = {};\n\n // Match 'groupName' => [ ... ]\n const groupRegex = /['\"](\\w+)['\"]\\s*=>\\s*\\[([\\s\\S]*?)\\]/g;\n let gMatch: RegExpExecArray | null;\n while ((gMatch = groupRegex.exec(body)) !== null) {\n groups[gMatch[1]] = extractClassReferences(gMatch[2]);\n }\n\n return groups;\n}\n\n/**\n * Extract a property that is a map of alias name -> class reference.\n * e.g. protected $routeMiddleware = [ 'auth' => \\App\\Http\\Middleware\\Authenticate::class, ... ];\n */\nfunction extractPropertyMap(\n source: string,\n propName: string,\n): Record<string, string> {\n const escaped = escapeRegExp(propName);\n const regex = new RegExp(\n `protected\\\\s+${escaped}\\\\s*=\\\\s*\\\\[([\\\\s\\\\S]*?)\\\\];`,\n );\n const match = source.match(regex);\n if (!match) return {};\n\n return extractAliasMap(match[1]);\n}\n\n/**\n * Extract alias map from $middleware->alias([...]) call in bootstrap/app.php.\n */\nfunction extractCallMap(body: string, methodName: string): Record<string, string> {\n const regex = new RegExp(\n `\\\\$middleware->${escapeRegExp(methodName)}\\\\s*\\\\(\\\\s*\\\\[([\\\\s\\\\S]*?)\\\\]\\\\s*\\\\)`,\n );\n const match = body.match(regex);\n if (!match) return {};\n return extractAliasMap(match[1]);\n}\n\n/**\n * Extract class array from $middleware->web(append: [...]) or $middleware->api(prepend: [...]).\n */\nfunction extractCallArray(body: string, methodName: string): string[] {\n const regex = new RegExp(\n `\\\\$middleware->${escapeRegExp(methodName)}\\\\s*\\\\((?:append|prepend):\\\\s*\\\\[([\\\\s\\\\S]*?)\\\\]\\\\s*\\\\)`,\n );\n const match = body.match(regex);\n if (!match) return [];\n return extractClassReferences(match[1]);\n}\n\n/**\n * Extract class references from a PHP array body.\n * Handles both \\Full\\Class::class and 'string:param' forms.\n */\nfunction extractClassReferences(body: string): string[] {\n const refs: string[] = [];\n\n // Match ::class references\n const classRegex = /\\\\?([\\w\\\\]+)::class/g;\n let m: RegExpExecArray | null;\n while ((m = classRegex.exec(body)) !== null) {\n refs.push(m[1]);\n }\n\n // Match string references like 'throttle:60,1' or 'throttle:api'\n const stringRegex = /['\"](\\w+[:\\w,]*)['\"]/g;\n while ((m = stringRegex.exec(body)) !== null) {\n // Skip if it's a group name key (followed by =>)\n const afterMatch = body.substring(m.index + m[0].length).trimStart();\n if (afterMatch.startsWith('=>')) continue;\n refs.push(m[1]);\n }\n\n return refs;\n}\n\n/**\n * Extract alias mappings from PHP array body: 'name' => \\Class::class\n */\nfunction extractAliasMap(body: string): Record<string, string> {\n const map: Record<string, string> = {};\n const regex = /['\"](\\w+)['\"]\\s*=>\\s*\\\\?([\\w\\\\]+)::class/g;\n let m: RegExpExecArray | null;\n while ((m = regex.exec(body)) !== null) {\n map[m[1]] = m[2];\n }\n return map;\n}\n\n/**\n * Extract RouteServiceProvider namespace (Laravel 6-8).\n * Returns the $namespace property value.\n */\nexport function parseRouteServiceProviderNamespace(source: string): string | null {\n const match = source.match(/protected\\s+\\$namespace\\s*=\\s*['\"]([^'\"]+)['\"]/);\n return match ? match[1] : null;\n}\n\n/**\n * Extract withRouting() config from bootstrap/app.php (Laravel 11+).\n * Returns which route files are configured.\n */\nexport function parseBootstrapRouting(source: string): Record<string, string> {\n const routes: Record<string, string> = {};\n const routingRegex = /->withRouting\\s*\\(([\\s\\S]*?)\\)/;\n const match = source.match(routingRegex);\n if (!match) return routes;\n\n const body = match[1];\n // Match named params: web: __DIR__.'/../routes/web.php'\n const paramRegex = /(\\w+):\\s*(?:__DIR__\\s*\\.\\s*)?['\"]([^'\"]+)['\"]/g;\n let m: RegExpExecArray | null;\n while ((m = paramRegex.exec(body)) !== null) {\n const key = m[1];\n let value = m[2];\n // Normalize: remove leading /../ or ../ or / patterns\n value = value.replace(/^\\/?\\.\\.\\//, '').replace(/^\\//, '');\n routes[key] = value;\n }\n\n return routes;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\nimport { resolveComponentTag, toKebabCase, toPascalCase } from './resolver.js';\n\nexport class VueFrameworkPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'vue-framework',\n version: '1.0.0',\n priority: 10,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n return 'vue' in deps;\n }\n\n // Fallback: try reading package.json from rootPath\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content) as Record<string, unknown>;\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n return 'vue' in deps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'renders_component', category: 'vue', description: 'Parent component renders child in template' },\n { name: 'uses_composable', category: 'vue', description: 'Component calls a composable function' },\n { name: 'provides_slot', category: 'vue', description: 'Component provides a named slot' },\n ],\n };\n }\n\n extractNodes(\n _filePath: string,\n _content: Buffer,\n _language: string,\n ): TraceMcpResult<FileParseResult> {\n // The VueLanguagePlugin already extracts symbols and components.\n // Framework-level resolution happens in resolveEdges.\n return ok({ status: 'ok', symbols: [] });\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n const allFiles = ctx.getAllFiles();\n\n const vueFiles = allFiles.filter((f) => f.path.endsWith('.vue'));\n const composableFiles = allFiles.filter(\n (f) => (f.path.endsWith('.ts') || f.path.endsWith('.js')) && /\\/use[A-Z]/.test(f.path),\n );\n\n // Map component name -> symbolId for all .vue files\n const componentNameToSymbolId = new Map<string, string>();\n const componentNameToFilePath = new Map<string, string>();\n\n for (const file of vueFiles) {\n const symbols = ctx.getSymbolsByFile(file.id);\n const compSymbol = symbols.find((s) => s.kind === 'class');\n if (compSymbol) {\n componentNameToSymbolId.set(compSymbol.name, compSymbol.symbolId);\n componentNameToFilePath.set(compSymbol.name, file.path);\n }\n }\n\n // Map composable function name -> symbolId\n const composableNameToSymbolId = new Map<string, string>();\n for (const file of composableFiles) {\n const symbols = ctx.getSymbolsByFile(file.id);\n for (const sym of symbols) {\n if (sym.kind === 'function' && sym.name.startsWith('use')) {\n composableNameToSymbolId.set(sym.name, sym.symbolId);\n }\n }\n }\n\n // For each .vue file, resolve template components and composables\n for (const file of vueFiles) {\n const symbols = ctx.getSymbolsByFile(file.id);\n const compSymbol = symbols.find((s) => s.kind === 'class');\n if (!compSymbol) continue;\n\n const metadata = compSymbol.metadata as Record<string, unknown> | null | undefined;\n const templateComponents = (metadata?.templateComponents as string[]) ?? [];\n const composables = (metadata?.composables as string[]) ?? [];\n\n const importMap = this.buildImportMap(ctx, file);\n\n // Resolve renders_component edges\n for (const tag of templateComponents) {\n const targetPath = resolveComponentTag(tag, importMap, componentNameToFilePath);\n if (!targetPath) continue;\n\n const targetName = targetPath.split('/').pop()?.replace(/\\.vue$/, '');\n if (!targetName) continue;\n\n const targetSymbolId = componentNameToSymbolId.get(targetName);\n if (!targetSymbolId) continue;\n\n edges.push({\n sourceSymbolId: compSymbol.symbolId,\n targetSymbolId,\n edgeType: 'renders_component',\n metadata: { tag },\n });\n }\n\n // Resolve uses_composable edges\n for (const composableName of composables) {\n const targetSymbolId = composableNameToSymbolId.get(composableName);\n if (!targetSymbolId) continue;\n\n edges.push({\n sourceSymbolId: compSymbol.symbolId,\n targetSymbolId,\n edgeType: 'uses_composable',\n metadata: { composable: composableName },\n });\n }\n }\n\n return ok(edges);\n }\n\n /**\n * Build a map of component name -> file path for all known .vue files.\n * Registers PascalCase and kebab-case variants for each component.\n */\n private buildImportMap(\n ctx: ResolveContext,\n currentFile: { id: number; path: string },\n ): Map<string, string> {\n const importMap = new Map<string, string>();\n const allFiles = ctx.getAllFiles();\n\n for (const f of allFiles) {\n if (!f.path.endsWith('.vue') || f.path === currentFile.path) continue;\n const compName = f.path.split('/').pop()?.replace(/\\.vue$/, '');\n if (!compName) continue;\n\n importMap.set(compName, f.path);\n importMap.set(toKebabCase(compName), f.path);\n importMap.set(toPascalCase(compName), f.path);\n }\n\n return importMap;\n }\n}\n","/**\n * Vue component name resolution.\n *\n * Converts between PascalCase and kebab-case, and resolves component tags\n * to actual file paths using import maps and auto-registration conventions.\n */\n\n/** Convert PascalCase to kebab-case: \"UserCard\" -> \"user-card\" */\nexport function toKebabCase(name: string): string {\n return name\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')\n .toLowerCase();\n}\n\n/** Convert kebab-case to PascalCase: \"user-card\" -> \"UserCard\" */\nexport function toPascalCase(name: string): string {\n return name\n .split('-')\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))\n .join('');\n}\n\n/**\n * Resolve a template component tag to a file path.\n *\n * Resolution order:\n * 1. Check explicit imports (exact match or PascalCase/kebab-case variants)\n * 2. Check auto-registered component files by name convention\n *\n * @param tag - The component tag from the template (e.g. \"UserCard\" or \"user-card\")\n * @param imports - Map of imported name -> file path (from script imports)\n * @param componentFiles - Map of component name -> file path (auto-registered)\n * @returns The resolved file path, or undefined if not found\n */\nexport function resolveComponentTag(\n tag: string,\n imports: Map<string, string>,\n componentFiles: Map<string, string>,\n): string | undefined {\n // 1. Direct import match\n if (imports.has(tag)) return imports.get(tag);\n\n // 2. Try PascalCase variant of the tag\n const pascal = toPascalCase(tag);\n if (imports.has(pascal)) return imports.get(pascal);\n\n // 3. Try kebab-case variant of the tag\n const kebab = toKebabCase(tag);\n if (imports.has(kebab)) return imports.get(kebab);\n\n // 4. Auto-registered by PascalCase name\n if (componentFiles.has(tag)) return componentFiles.get(tag);\n if (componentFiles.has(pascal)) return componentFiles.get(pascal);\n\n // 5. Auto-registered by kebab-case name\n if (componentFiles.has(kebab)) return componentFiles.get(kebab);\n\n return undefined;\n}\n","/**\n * InertiaPlugin — detects Inertia::render() calls in PHP controllers\n * and links them to Vue page components.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\nexport interface InertiaRenderCall {\n pageName: string;\n propNames: string[];\n line: number;\n}\n\n/** Regex for Inertia::render('Page/Name', [...]) or inertia('Page/Name', [...]) */\nconst INERTIA_RENDER_RE =\n /(?:Inertia::render|inertia)\\(\\s*['\"]([\\w/.-]+)['\"]\\s*(?:,\\s*\\[([^\\]]*)\\])?\\s*\\)/g;\n\n/** Extract array keys from a PHP associative array literal */\nconst ARRAY_KEY_RE = /['\"](\\w+)['\"]\\s*=>/g;\n\nexport function extractInertiaRenders(source: string): InertiaRenderCall[] {\n const calls: InertiaRenderCall[] = [];\n let match: RegExpExecArray | null;\n\n const re = new RegExp(INERTIA_RENDER_RE.source, 'g');\n while ((match = re.exec(source)) !== null) {\n const pageName = match[1];\n const propsBlock = match[2] ?? '';\n const propNames: string[] = [];\n\n let keyMatch: RegExpExecArray | null;\n const keyRe = new RegExp(ARRAY_KEY_RE.source, 'g');\n while ((keyMatch = keyRe.exec(propsBlock)) !== null) {\n propNames.push(keyMatch[1]);\n }\n\n // Find line number\n const before = source.substring(0, match.index);\n const line = before.split('\\n').length;\n\n calls.push({ pageName, propNames, line });\n }\n\n return calls;\n}\n\nexport function resolvePagePath(pageName: string): string {\n return `resources/js/Pages/${pageName}.vue`;\n}\n\nexport class InertiaPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'inertia',\n version: '1.0.0',\n priority: 20,\n dependencies: ['laravel', 'vue-framework'],\n };\n\n detect(ctx: ProjectContext): boolean {\n // Check composer.json for inertiajs/inertia-laravel\n if (ctx.composerJson) {\n const req = ctx.composerJson.require as Record<string, string> | undefined;\n if (req?.['inertiajs/inertia-laravel']) return true;\n }\n\n // Check package.json for @inertiajs/vue3 or @inertiajs/react\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if ('@inertiajs/vue3' in deps || '@inertiajs/react' in deps) return true;\n }\n\n // Fallback: read from disk\n try {\n const composerPath = path.join(ctx.rootPath, 'composer.json');\n const content = fs.readFileSync(composerPath, 'utf-8');\n const json = JSON.parse(content);\n const req = json.require as Record<string, string> | undefined;\n if (req?.['inertiajs/inertia-laravel']) return true;\n } catch { /* ignore */ }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n if ('@inertiajs/vue3' in deps || '@inertiajs/react' in deps) return true;\n } catch { /* ignore */ }\n\n return false;\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'inertia_renders', category: 'inertia', description: 'Controller renders Vue page via Inertia' },\n { name: 'passes_props', category: 'inertia', description: 'Controller passes props to Vue page' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'php') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const renders = extractInertiaRenders(source);\n\n if (renders.length === 0) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n // Store Inertia render metadata on the file for pass 2\n return ok({\n status: 'ok',\n symbols: [],\n frameworkRole: 'inertia_controller',\n });\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n const allFiles = ctx.getAllFiles();\n\n for (const file of allFiles) {\n if (file.language !== 'php') continue;\n\n let source: string;\n try {\n source = fs.readFileSync(path.resolve(ctx.rootPath, file.path), 'utf-8');\n } catch { continue; }\n\n const renders = extractInertiaRenders(source);\n if (renders.length === 0) continue;\n\n const symbols = ctx.getSymbolsByFile(file.id);\n const controllerClass = symbols.find((s) => s.kind === 'class');\n if (!controllerClass) continue;\n\n for (const render of renders) {\n const pagePath = resolvePagePath(render.pageName);\n const pageFile = allFiles.find((f) => f.path === pagePath);\n if (!pageFile) continue;\n\n const pageSymbols = ctx.getSymbolsByFile(pageFile.id);\n const pageComponent = pageSymbols.find((s) => s.kind === 'class');\n if (!pageComponent) continue;\n\n // Find the method that contains this render call by line range\n const method = symbols.find(\n (s) => s.kind === 'method' &&\n s.lineStart != null && s.lineEnd != null &&\n render.line >= s.lineStart &&\n render.line <= s.lineEnd,\n );\n const sourceSymbol = method ?? controllerClass;\n\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: sourceSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: pageComponent.id,\n edgeType: 'inertia_renders',\n metadata: {\n pageName: render.pageName,\n propNames: render.propNames,\n },\n });\n\n // passes_props edge for each prop\n if (render.propNames.length > 0) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: sourceSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: pageComponent.id,\n edgeType: 'passes_props',\n metadata: {\n propNames: render.propNames,\n pageName: render.pageName,\n },\n });\n }\n }\n }\n\n return ok(edges);\n }\n}\n\n/**\n * Detect prop mismatches between PHP-side Inertia::render props and Vue defineProps.\n */\nexport interface PropMismatch {\n pageName: string;\n pagePath: string;\n phpProps: string[];\n vueProps: string[];\n missingInVue: string[];\n missingInPhp: string[];\n}\n\nexport function detectPropMismatches(\n inertiaRenders: { pageName: string; propNames: string[] }[],\n vuePages: Map<string, string[]>,\n): PropMismatch[] {\n const mismatches: PropMismatch[] = [];\n\n for (const render of inertiaRenders) {\n const pagePath = resolvePagePath(render.pageName);\n const vueProps = vuePages.get(render.pageName);\n if (!vueProps) continue;\n\n const missingInVue = render.propNames.filter((p) => !vueProps.includes(p));\n const missingInPhp = vueProps.filter((p) => !render.propNames.includes(p));\n\n if (missingInVue.length > 0 || missingInPhp.length > 0) {\n mismatches.push({\n pageName: render.pageName,\n pagePath,\n phpProps: render.propNames,\n vueProps,\n missingInVue,\n missingInPhp,\n });\n }\n }\n\n return mismatches;\n}\n","/**\n * NuxtPlugin — detects Nuxt 3 and Nuxt 4 projects and extracts file-based routes,\n * auto-imported composables, shared utilities, and API routes.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\n/**\n * Convert a Nuxt pages file path to a route URI.\n * pages/index.vue -> /\n * pages/users.vue -> /users\n * pages/users/index.vue -> /users\n * pages/users/[id].vue -> /users/:id\n * pages/[...slug].vue -> /:slug(.*)*\n *\n * Accepts an optional srcDir to strip the correct prefix (e.g. 'app' for Nuxt 4).\n */\nexport function filePathToRoute(filePath: string, srcDir: string = '.'): string {\n // Normalize: remove {srcDir}/pages/ prefix and .vue suffix\n const pagesPrefix = srcDir === '.' ? 'pages/' : `${srcDir}/pages/`;\n let route = filePath\n .replace(new RegExp(`^${pagesPrefix.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}`), '')\n .replace(/\\.vue$/, '');\n\n // Handle index files\n route = route.replace(/\\/index$/, '');\n if (route === 'index') route = '';\n\n // Convert path segments\n const segments = route.split('/').filter(Boolean);\n const routeSegments = segments.map((seg) => {\n // Catch-all: [...slug] -> :slug(.*)*\n const catchAll = seg.match(/^\\[\\.\\.\\.(\\w+)\\]$/);\n if (catchAll) return `:${catchAll[1]}(.*)*`;\n\n // Dynamic: [id] -> :id\n const dynamic = seg.match(/^\\[(\\w+)\\]$/);\n if (dynamic) return `:${dynamic[1]}`;\n\n return seg;\n });\n\n return '/' + routeSegments.join('/');\n}\n\n/**\n * Convert a server/api file path to an API route.\n * server/api/users.get.ts -> GET /api/users\n * server/api/users.ts -> GET /api/users (default GET)\n */\nexport function serverApiToRoute(filePath: string): { method: string; uri: string } {\n // Extract HTTP method from filename suffix (e.g., users.get.ts)\n const methodMatch = filePath.match(/\\.(get|post|put|patch|delete|head|options)\\.(ts|js|mjs)$/);\n\n let route = filePath.replace(/^server\\//, '');\n if (methodMatch) {\n // Remove .method.ext\n route = route.replace(/\\.(get|post|put|patch|delete|head|options)\\.(ts|js|mjs)$/, '');\n } else {\n // Remove .ext only\n route = route.replace(/\\.(ts|js|mjs)$/, '');\n }\n\n const method = methodMatch ? methodMatch[1].toUpperCase() : 'GET';\n\n // Handle index files\n route = route.replace(/\\/index$/, '');\n\n return { method, uri: '/' + route };\n}\n\n/**\n * Convert a server/routes file path to a route (no /api prefix).\n * server/routes/health.ts -> GET /health\n * server/routes/webhook.post.ts -> POST /webhook\n */\nexport function serverRoutesToRoute(filePath: string): { method: string; uri: string } {\n const methodMatch = filePath.match(/\\.(get|post|put|patch|delete|head|options)\\.(ts|js|mjs)$/);\n\n let route = filePath.replace(/^server\\/routes\\//, '');\n if (methodMatch) {\n route = route.replace(/\\.(get|post|put|patch|delete|head|options)\\.(ts|js|mjs)$/, '');\n } else {\n route = route.replace(/\\.(ts|js|mjs)$/, '');\n }\n\n const method = methodMatch ? methodMatch[1].toUpperCase() : 'GET';\n\n // Handle index files\n route = route.replace(/\\/index$/, '');\n if (route === 'index') route = '';\n\n return { method, uri: '/' + route };\n}\n\n/** Detect useFetch / useAsyncData calls and extract the API URL. */\nconst USE_FETCH_RE = /(?:useFetch|useAsyncData)\\(\\s*[`'\"](\\/[^`'\"]*)[`'\"]/g;\n\nexport function extractFetchCalls(source: string): string[] {\n const urls: string[] = [];\n let match: RegExpExecArray | null;\n const re = new RegExp(USE_FETCH_RE.source, 'g');\n while ((match = re.exec(source)) !== null) {\n urls.push(match[1]);\n }\n return urls;\n}\n\nexport class NuxtPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'nuxt',\n version: '1.0.0',\n priority: 15,\n dependencies: ['vue-framework'],\n };\n\n private nuxt4: boolean = false;\n private srcDir: string = '.';\n\n /**\n * Detect whether the project uses Nuxt 4.\n * Checks: package.json version, nuxt.config.ts compatibilityVersion, app/pages/ directory.\n */\n private isNuxt4(ctx: ProjectContext): boolean {\n // Check package.json nuxt version\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n const nuxtVersion = deps['nuxt'];\n if (nuxtVersion && (/\\^4/.test(nuxtVersion) || />=\\s*4\\.0\\.0/.test(nuxtVersion))) {\n return true;\n }\n }\n\n // Check nuxt.config.ts for compatibilityVersion: 4\n try {\n const configPath = path.join(ctx.rootPath, 'nuxt.config.ts');\n const configContent = fs.readFileSync(configPath, 'utf-8');\n if (/compatibilityVersion\\s*:\\s*4/.test(configContent)) {\n return true;\n }\n } catch { /* ignore */ }\n\n // Structural heuristic: check if app/pages/ exists\n try {\n const appPagesDir = path.join(ctx.rootPath, 'app', 'pages');\n fs.accessSync(appPagesDir);\n return true;\n } catch { /* ignore */ }\n\n return false;\n }\n\n /** Returns 'app' for Nuxt 4, '.' for Nuxt 3. */\n getSrcDir(): string {\n return this.srcDir;\n }\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if ('nuxt' in deps) {\n this.nuxt4 = this.isNuxt4(ctx);\n this.srcDir = this.nuxt4 ? 'app' : '.';\n return true;\n }\n }\n\n // Check for nuxt.config.ts\n try {\n const configPath = path.join(ctx.rootPath, 'nuxt.config.ts');\n fs.accessSync(configPath);\n this.nuxt4 = this.isNuxt4(ctx);\n this.srcDir = this.nuxt4 ? 'app' : '.';\n return true;\n } catch { /* ignore */ }\n\n // Fallback: read package.json from disk\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n if ('nuxt' in deps) {\n this.nuxt4 = this.isNuxt4(ctx);\n this.srcDir = this.nuxt4 ? 'app' : '.';\n return true;\n }\n } catch { /* ignore */ }\n\n return false;\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'nuxt_auto_imports', category: 'nuxt', description: 'Auto-imported composable' },\n { name: 'api_calls', category: 'nuxt', description: 'fetch/useFetch API call' },\n { name: 'nuxt_shared_import', category: 'nuxt', description: 'Auto-imported shared utility or type' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n const result: FileParseResult = { status: 'ok', symbols: [], routes: [] };\n\n const srcDir = this.srcDir;\n const pagesPrefix = srcDir === '.' ? 'pages/' : `${srcDir}/pages/`;\n const composablesPrefix = srcDir === '.' ? 'composables/' : `${srcDir}/composables/`;\n const pluginsPrefix = srcDir === '.' ? 'plugins/' : `${srcDir}/plugins/`;\n const middlewarePrefix = srcDir === '.' ? 'middleware/' : `${srcDir}/middleware/`;\n const layoutsPrefix = srcDir === '.' ? 'layouts/' : `${srcDir}/layouts/`;\n\n // Nuxt page -> route\n if (filePath.startsWith(pagesPrefix) && filePath.endsWith('.vue')) {\n const uri = filePathToRoute(filePath, srcDir);\n result.routes!.push({\n method: 'GET',\n uri,\n name: filePath.replace(new RegExp(`^${pagesPrefix.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}`), '').replace(/\\.vue$/, '').replace(/\\//g, '-'),\n });\n result.frameworkRole = 'nuxt_page';\n }\n\n // Composable\n if (filePath.startsWith(composablesPrefix) && /\\.(ts|js)$/.test(filePath)) {\n result.frameworkRole = 'nuxt_composable';\n }\n\n // Plugin\n if (filePath.startsWith(pluginsPrefix) && /\\.(ts|js)$/.test(filePath)) {\n result.frameworkRole = 'nuxt_plugin';\n }\n\n // Middleware\n if (filePath.startsWith(middlewarePrefix) && /\\.(ts|js)$/.test(filePath)) {\n result.frameworkRole = 'nuxt_middleware';\n }\n\n // Layout\n if (filePath.startsWith(layoutsPrefix) && filePath.endsWith('.vue')) {\n result.frameworkRole = 'nuxt_layout';\n }\n\n // Server API route (always at project root)\n if (filePath.startsWith('server/api/') && /\\.(ts|js|mjs)$/.test(filePath)) {\n const { method, uri } = serverApiToRoute(filePath);\n result.routes!.push({ method, uri });\n result.frameworkRole = 'nuxt_api';\n }\n\n // Server routes (always at project root, no /api prefix)\n if (filePath.startsWith('server/routes/') && /\\.(ts|js|mjs)$/.test(filePath)) {\n const { method, uri } = serverRoutesToRoute(filePath);\n result.routes!.push({ method, uri });\n result.frameworkRole = 'nuxt_server_route';\n }\n\n // Shared utils and types (Nuxt 4 auto-imports)\n if (\n (filePath.startsWith('shared/utils/') || filePath.startsWith('shared/types/')) &&\n /\\.(ts|js)$/.test(filePath)\n ) {\n result.frameworkRole = 'nuxt_shared';\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n const allFiles = ctx.getAllFiles();\n\n const srcDir = this.srcDir;\n const composablesPrefix = srcDir === '.' ? 'composables/' : `${srcDir}/composables/`;\n\n // Find composable files\n const composableFiles = allFiles.filter(\n (f) => f.path.startsWith(composablesPrefix) && /\\.(ts|js)$/.test(f.path),\n );\n\n // Map composable name -> symbol\n const composableMap = new Map<string, { id: number; symbolId: string }>();\n for (const file of composableFiles) {\n const symbols = ctx.getSymbolsByFile(file.id);\n for (const sym of symbols) {\n if (sym.kind === 'function' && sym.name.startsWith('use')) {\n composableMap.set(sym.name, { id: sym.id, symbolId: sym.symbolId });\n }\n }\n }\n\n // Find shared files\n const sharedFiles = allFiles.filter(\n (f) =>\n (f.path.startsWith('shared/utils/') || f.path.startsWith('shared/types/')) &&\n /\\.(ts|js)$/.test(f.path),\n );\n\n // Map shared export name -> symbol\n const sharedMap = new Map<string, { id: number; symbolId: string }>();\n for (const file of sharedFiles) {\n const symbols = ctx.getSymbolsByFile(file.id);\n for (const sym of symbols) {\n if (sym.kind === 'function' || sym.kind === 'interface' || sym.kind === 'type' || sym.kind === 'variable') {\n sharedMap.set(sym.name, { id: sym.id, symbolId: sym.symbolId });\n }\n }\n }\n\n // For each Vue file, detect auto-imported composable and shared usage\n const vueFiles = allFiles.filter((f) => f.path.endsWith('.vue'));\n for (const file of vueFiles) {\n let source: string;\n try {\n source = fs.readFileSync(path.resolve(ctx.rootPath, file.path), 'utf-8');\n } catch { continue; }\n\n const symbols = ctx.getSymbolsByFile(file.id);\n const compSymbol = symbols.find((s) => s.kind === 'class');\n if (!compSymbol) continue;\n\n // Check for composable usage\n for (const [name, target] of composableMap) {\n if (source.includes(name)) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: compSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: target.id,\n edgeType: 'nuxt_auto_imports',\n metadata: { composable: name },\n });\n }\n }\n\n // Check for shared utility/type usage\n for (const [name, target] of sharedMap) {\n if (source.includes(name)) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: compSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: target.id,\n edgeType: 'nuxt_shared_import',\n metadata: { shared: name },\n });\n }\n }\n }\n\n return ok(edges);\n }\n}\n","/**\n * BladePlugin — detects Blade template directives and creates edges\n * for @extends, @include, @component, and <x-component> usage.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\nexport interface BladeDirective {\n type: 'extends' | 'include' | 'component' | 'x-component';\n name: string;\n line: number;\n}\n\n/** Detect @extends('layout.name') */\nconst EXTENDS_RE = /@extends\\(\\s*['\"]([\\w.-]+)['\"]\\s*\\)/g;\n\n/** Detect @include('partial.name') and @includeIf, @includeWhen etc. */\nconst INCLUDE_RE = /@include(?:If|When|Unless|First)?\\(\\s*['\"]([\\w.-]+)['\"]/g;\n\n/** Detect @component('component.name') */\nconst COMPONENT_RE = /@component\\(\\s*['\"]([\\w.-]+)['\"]/g;\n\n/** Detect <x-component-name> (Blade anonymous/class components) */\nconst X_COMPONENT_RE = /<x-([\\w.-]+)/g;\n\n/** Detect @section('name') */\nconst SECTION_RE = /@section\\(\\s*['\"]([\\w.-]+)['\"]/g;\n\n/** Detect @yield('name') */\nconst YIELD_RE = /@yield\\(\\s*['\"]([\\w.-]+)['\"]/g;\n\nexport function extractBladeDirectives(source: string): BladeDirective[] {\n const directives: BladeDirective[] = [];\n\n const extract = (re: RegExp, type: BladeDirective['type']) => {\n let match: RegExpExecArray | null;\n const regex = new RegExp(re.source, 'g');\n while ((match = regex.exec(source)) !== null) {\n const before = source.substring(0, match.index);\n const line = before.split('\\n').length;\n directives.push({ type, name: match[1], line });\n }\n };\n\n extract(EXTENDS_RE, 'extends');\n extract(INCLUDE_RE, 'include');\n extract(COMPONENT_RE, 'component');\n extract(X_COMPONENT_RE, 'x-component');\n\n return directives;\n}\n\nexport function extractBladeSections(source: string): string[] {\n const sections: string[] = [];\n let match: RegExpExecArray | null;\n const re = new RegExp(SECTION_RE.source, 'g');\n while ((match = re.exec(source)) !== null) {\n sections.push(match[1]);\n }\n return sections;\n}\n\nexport function extractBladeYields(source: string): string[] {\n const yields: string[] = [];\n let match: RegExpExecArray | null;\n const re = new RegExp(YIELD_RE.source, 'g');\n while ((match = re.exec(source)) !== null) {\n yields.push(match[1]);\n }\n return yields;\n}\n\n/**\n * Convert a Blade dot-notation view name to a file path.\n * 'layouts.app' -> 'resources/views/layouts/app.blade.php'\n */\nexport function bladeNameToPath(name: string): string {\n return `resources/views/${name.replace(/\\./g, '/')}.blade.php`;\n}\n\n/**\n * Convert an x-component name to possible file paths.\n * 'user-card' -> 'resources/views/components/user-card.blade.php'\n */\nexport function xComponentToPath(name: string): string {\n return `resources/views/components/${name}.blade.php`;\n}\n\nexport class BladePlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'blade',\n version: '1.0.0',\n priority: 5,\n dependencies: ['laravel'],\n };\n\n detect(ctx: ProjectContext): boolean {\n // Check if resources/views/ exists with .blade.php files\n try {\n const viewsDir = path.join(ctx.rootPath, 'resources', 'views');\n const stat = fs.statSync(viewsDir);\n if (!stat.isDirectory()) return false;\n // Quick check: any .blade.php in the directory tree\n return this.hasBlade(viewsDir);\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'blade_extends', category: 'blade', description: '@extends directive' },\n { name: 'blade_includes', category: 'blade', description: '@include directive' },\n { name: 'blade_component', category: 'blade', description: '<x-component> or @component' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n _language: string,\n ): TraceMcpResult<FileParseResult> {\n if (!filePath.endsWith('.blade.php')) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const sections = extractBladeSections(source);\n const yields = extractBladeYields(source);\n\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n frameworkRole: yields.length > 0 ? 'blade_layout' : 'blade_view',\n };\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n const allFiles = ctx.getAllFiles();\n\n // Build file path -> file map\n const fileMap = new Map<string, { id: number; path: string }>();\n for (const f of allFiles) {\n fileMap.set(f.path, f);\n }\n\n for (const file of allFiles) {\n if (!file.path.endsWith('.blade.php')) continue;\n\n const source = ctx.readFile(file.path);\n if (!source) continue;\n\n const directives = extractBladeDirectives(source);\n if (directives.length === 0) continue;\n\n const sourceNodeId = ctx.createNodeIfNeeded('file', file.id);\n\n for (const dir of directives) {\n let targetPath: string;\n let edgeType: string;\n\n switch (dir.type) {\n case 'extends':\n targetPath = bladeNameToPath(dir.name);\n edgeType = 'blade_extends';\n break;\n case 'include':\n targetPath = bladeNameToPath(dir.name);\n edgeType = 'blade_includes';\n break;\n case 'component':\n targetPath = bladeNameToPath(dir.name);\n edgeType = 'blade_component';\n break;\n case 'x-component':\n targetPath = xComponentToPath(dir.name);\n edgeType = 'blade_component';\n break;\n }\n\n const targetFile = fileMap.get(targetPath);\n if (!targetFile) continue;\n\n const targetNodeId = ctx.createNodeIfNeeded('file', targetFile.id);\n\n edges.push({\n sourceNodeType: 'file',\n sourceRefId: file.id,\n targetNodeType: 'file',\n targetRefId: targetFile.id,\n edgeType,\n metadata: { directive: dir.type, name: dir.name, line: dir.line },\n });\n }\n }\n\n return ok(edges);\n }\n\n private hasBlade(dir: string): boolean {\n try {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith('.blade.php')) return true;\n if (entry.isDirectory()) {\n if (this.hasBlade(path.join(dir, entry.name))) return true;\n }\n }\n } catch { /* ignore */ }\n return false;\n }\n}\n","/**\n * NextJSPlugin — detects Next.js projects and extracts file-based routes\n * for both App Router and Pages Router, including parallel routes,\n * intercepting routes, data fetching functions, and template/default files.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\nconst PAGE_EXTENSIONS = /\\.(tsx|ts|jsx|js)$/;\nconst APP_ROUTER_FILES = ['page', 'layout', 'loading', 'error', 'not-found', 'route', 'template', 'default'] as const;\nconst API_ROUTE_EXPORTS_RE = /export\\s+(?:async\\s+)?function\\s+(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)\\b/g;\nconst USE_SERVER_RE = /['\"]use server['\"]/;\nconst DATA_FETCHING_RE = /export\\s+async\\s+function\\s+(getStaticProps|getServerSideProps|getStaticPaths)\\b/g;\n\n/**\n * Convert an App Router file path to a route URI.\n * app/page.tsx -> /\n * app/users/page.tsx -> /users\n * app/users/[id]/page.tsx -> /users/:id\n * app/blog/[...slug]/page.tsx -> /blog/:slug*\n * app/(group)/page.tsx -> / (route groups stripped)\n */\nexport function appRouterPathToRoute(filePath: string): string {\n // Remove app/ prefix and file name\n let route = filePath.replace(/^app\\//, '');\n // Remove the filename part (page.tsx, layout.tsx, etc.)\n const parts = route.split('/');\n parts.pop(); // remove filename\n route = parts.join('/');\n\n if (!route) return '/';\n\n const segments = route.split('/').filter(Boolean);\n const routeSegments = segments\n .filter((seg) => !seg.startsWith('(')) // strip route groups and intercepting prefixes\n .filter((seg) => !seg.startsWith('@')) // strip parallel route slots\n .map((seg) => {\n // Catch-all: [...slug] -> :slug*\n const catchAll = seg.match(/^\\[\\.\\.\\.(\\w+)\\]$/);\n if (catchAll) return `:${catchAll[1]}*`;\n\n // Optional catch-all: [[...slug]] -> :slug*\n const optCatchAll = seg.match(/^\\[\\[\\.\\.\\.(\\w+)\\]\\]$/);\n if (optCatchAll) return `:${optCatchAll[1]}*`;\n\n // Dynamic: [id] -> :id\n const dynamic = seg.match(/^\\[(\\w+)\\]$/);\n if (dynamic) return `:${dynamic[1]}`;\n\n return seg;\n });\n\n return '/' + routeSegments.join('/');\n}\n\n/**\n * Convert a Pages Router file path to a route URI.\n * pages/index.tsx -> /\n * pages/users/[id].tsx -> /users/:id\n * pages/api/users.ts -> /api/users\n */\nexport function pagesRouterPathToRoute(filePath: string): string {\n let route = filePath\n .replace(/^pages\\//, '')\n .replace(PAGE_EXTENSIONS, '');\n\n // Handle index\n route = route.replace(/\\/index$/, '');\n if (route === 'index') route = '';\n\n const segments = route.split('/').filter(Boolean);\n const routeSegments = segments.map((seg) => {\n const catchAll = seg.match(/^\\[\\.\\.\\.(\\w+)\\]$/);\n if (catchAll) return `:${catchAll[1]}*`;\n\n const dynamic = seg.match(/^\\[(\\w+)\\]$/);\n if (dynamic) return `:${dynamic[1]}`;\n\n return seg;\n });\n\n return '/' + routeSegments.join('/');\n}\n\n/** Determine the file type from an App Router path. */\nfunction getAppRouterFileType(filePath: string): string | null {\n const basename = path.basename(filePath).replace(PAGE_EXTENSIONS, '');\n if (APP_ROUTER_FILES.includes(basename as (typeof APP_ROUTER_FILES)[number])) {\n return basename;\n }\n return null;\n}\n\n/** Extract parallel route slot name from file path (e.g. @analytics). */\nfunction extractParallelSlot(filePath: string): string | null {\n const segments = filePath.split('/');\n for (const seg of segments) {\n if (seg.startsWith('@')) {\n return seg.slice(1); // remove @ prefix\n }\n }\n return null;\n}\n\n/**\n * Extract intercepting route info from file path.\n * Returns the intercept pattern and the intercepted route, or null.\n * e.g. app/feed/(..photos)/[id]/page.tsx -> { pattern: '..', interceptedRoute: '/photos/:id' }\n */\nfunction extractInterceptingInfo(filePath: string): { pattern: string; interceptedRoute: string } | null {\n const segments = filePath.replace(/^app\\//, '').split('/');\n segments.pop(); // remove filename\n\n for (let i = 0; i < segments.length; i++) {\n // Matches both formats: (.)detail, (..)photos, (...)photos AND (.detail), (..photos), (...photos)\n const match = segments[i].match(/^\\((\\.{1,3})\\)(.+)$/) || segments[i].match(/^\\((\\.{1,3})([^)]+)\\)$/);\n if (match) {\n const pattern = match[1]; // '.', '..', or '...'\n const routeName = match[2]; // e.g. 'photos'\n\n // Build the intercepted route from the remaining segments after the intercepting one\n const remaining = [routeName, ...segments.slice(i + 1)];\n const routeSegments = remaining.map((seg) => {\n const catchAll = seg.match(/^\\[\\.\\.\\.(\\w+)\\]$/);\n if (catchAll) return `:${catchAll[1]}*`;\n const dynamic = seg.match(/^\\[(\\w+)\\]$/);\n if (dynamic) return `:${dynamic[1]}`;\n return seg;\n });\n\n return {\n pattern,\n interceptedRoute: '/' + routeSegments.join('/'),\n };\n }\n }\n return null;\n}\n\n/** Extract Pages Router data fetching function names from source. */\nfunction extractDataFetchingFunctions(source: string): string[] {\n const fns: string[] = [];\n let match: RegExpExecArray | null;\n const re = new RegExp(DATA_FETCHING_RE.source, 'g');\n while ((match = re.exec(source)) !== null) {\n fns.push(match[1]);\n }\n return fns;\n}\n\nexport class NextJSPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'nextjs',\n version: '1.0.0',\n priority: 15,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if ('next' in deps) return true;\n }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n return 'next' in deps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'next_renders_page', category: 'nextjs', description: 'Layout renders page' },\n { name: 'next_server_action', category: 'nextjs', description: 'Server action reference' },\n { name: 'next_middleware', category: 'nextjs', description: 'Middleware applies to routes' },\n { name: 'next_parallel_slot', category: 'nextjs', description: 'Parallel route slot' },\n { name: 'next_intercepting', category: 'nextjs', description: 'Intercepting route' },\n { name: 'next_data_fetching', category: 'nextjs', description: 'Pages Router data fetching function' },\n { name: 'next_template', category: 'nextjs', description: 'Template component for route segment' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (!['typescript', 'typescriptreact', 'javascript', 'javascriptreact'].includes(language)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = { status: 'ok', symbols: [], routes: [], edges: [] };\n\n // App Router\n if (filePath.startsWith('app/')) {\n const fileType = getAppRouterFileType(filePath);\n const parallelSlot = extractParallelSlot(filePath);\n const interceptingInfo = extractInterceptingInfo(filePath);\n\n if (fileType === 'page') {\n const uri = appRouterPathToRoute(filePath);\n result.routes!.push({ method: 'GET', uri });\n result.frameworkRole = 'next_page';\n\n // Parallel route slot metadata\n if (parallelSlot) {\n result.metadata = {\n ...result.metadata,\n parallelSlot,\n };\n }\n\n // Intercepting route metadata\n if (interceptingInfo) {\n result.metadata = {\n ...result.metadata,\n intercepting: true,\n interceptPattern: interceptingInfo.pattern,\n interceptedRoute: interceptingInfo.interceptedRoute,\n };\n }\n } else if (fileType === 'layout') {\n result.frameworkRole = 'next_layout';\n } else if (fileType === 'loading') {\n result.frameworkRole = 'next_loading';\n } else if (fileType === 'error') {\n result.frameworkRole = 'next_error';\n } else if (fileType === 'template') {\n result.frameworkRole = 'next_template';\n } else if (fileType === 'default') {\n result.frameworkRole = 'next_default';\n if (parallelSlot) {\n result.metadata = {\n ...result.metadata,\n parallelSlot,\n };\n }\n } else if (fileType === 'route') {\n // API route handler — extract exported HTTP methods\n const methods = this.extractApiMethods(source);\n const uri = appRouterPathToRoute(filePath);\n for (const method of methods) {\n result.routes!.push({ method, uri });\n }\n result.frameworkRole = 'next_api_route';\n }\n }\n\n // Pages Router\n if (filePath.startsWith('pages/') && PAGE_EXTENSIONS.test(filePath)) {\n const uri = pagesRouterPathToRoute(filePath);\n if (filePath.startsWith('pages/api/')) {\n result.routes!.push({ method: 'ALL', uri });\n result.frameworkRole = 'next_api_page';\n } else {\n result.routes!.push({ method: 'GET', uri });\n result.frameworkRole = 'next_page';\n\n // Detect data fetching functions\n const dataFns = extractDataFetchingFunctions(source);\n if (dataFns.length > 0) {\n result.metadata = {\n ...result.metadata,\n dataFetching: dataFns,\n };\n }\n }\n }\n\n // Detect server actions\n if (USE_SERVER_RE.test(source)) {\n result.frameworkRole = result.frameworkRole ?? 'next_server_action';\n }\n\n // Detect middleware\n if (filePath === 'middleware.ts' || filePath === 'middleware.js') {\n result.frameworkRole = 'next_middleware';\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n const allFiles = ctx.getAllFiles();\n\n // Find layout files and their nested pages\n const layouts = allFiles.filter((f) => {\n const basename = path.basename(f.path).replace(PAGE_EXTENSIONS, '');\n return f.path.startsWith('app/') && basename === 'layout';\n });\n\n const pages = allFiles.filter((f) => {\n const basename = path.basename(f.path).replace(PAGE_EXTENSIONS, '');\n return f.path.startsWith('app/') && basename === 'page';\n });\n\n for (const layout of layouts) {\n const layoutDir = path.dirname(layout.path);\n const layoutSymbols = ctx.getSymbolsByFile(layout.id);\n const layoutSym = layoutSymbols.find((s) => s.kind === 'function' || s.kind === 'class');\n if (!layoutSym) continue;\n\n // Find pages nested under this layout\n for (const page of pages) {\n if (page.path.startsWith(layoutDir + '/') || layoutDir === 'app') {\n const pageSymbols = ctx.getSymbolsByFile(page.id);\n const pageSym = pageSymbols.find((s) => s.kind === 'function' || s.kind === 'class');\n if (!pageSym) continue;\n\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: layoutSym.id,\n targetNodeType: 'symbol',\n targetRefId: pageSym.id,\n edgeType: 'next_renders_page',\n });\n }\n }\n }\n\n // Parallel route slot edges\n const parallelPages = allFiles.filter((f) => {\n return f.path.startsWith('app/') && extractParallelSlot(f.path) !== null;\n });\n\n for (const file of parallelPages) {\n const slot = extractParallelSlot(file.path);\n if (!slot) continue;\n\n // Find the parent layout\n const segments = file.path.split('/');\n const slotIdx = segments.findIndex((s) => s.startsWith('@'));\n if (slotIdx < 1) continue;\n\n const parentDir = segments.slice(0, slotIdx).join('/');\n const parentLayout = allFiles.find((f) =>\n f.path.startsWith(parentDir + '/') &&\n !f.path.includes('@') &&\n /layout\\.(tsx|ts|jsx|js)$/.test(path.basename(f.path)),\n );\n\n if (parentLayout) {\n const layoutSymbols = ctx.getSymbolsByFile(parentLayout.id);\n const layoutSym = layoutSymbols.find((s) => s.kind === 'function' || s.kind === 'class');\n const fileSymbols = ctx.getSymbolsByFile(file.id);\n const fileSym = fileSymbols.find((s) => s.kind === 'function' || s.kind === 'class');\n\n if (layoutSym && fileSym) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: layoutSym.id,\n targetNodeType: 'symbol',\n targetRefId: fileSym.id,\n edgeType: 'next_parallel_slot',\n metadata: { slot },\n });\n }\n }\n }\n\n // Intercepting route edges\n const interceptingFiles = allFiles.filter((f) => {\n if (!f.path.startsWith('app/')) return false;\n return extractInterceptingInfo(f.path) !== null;\n });\n\n for (const file of interceptingFiles) {\n const info = extractInterceptingInfo(file.path);\n if (!info) continue;\n\n const fileSymbols = ctx.getSymbolsByFile(file.id);\n const fileSym = fileSymbols.find((s) => s.kind === 'function' || s.kind === 'class');\n if (!fileSym) continue;\n\n // Find the target page that matches the intercepted route\n const targetPage = pages.find((p) => {\n const pageRoute = appRouterPathToRoute(p.path);\n return pageRoute === info.interceptedRoute;\n });\n\n if (targetPage) {\n const targetSymbols = ctx.getSymbolsByFile(targetPage.id);\n const targetSym = targetSymbols.find((s) => s.kind === 'function' || s.kind === 'class');\n if (targetSym) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: fileSym.id,\n targetNodeType: 'symbol',\n targetRefId: targetSym.id,\n edgeType: 'next_intercepting',\n metadata: {\n pattern: info.pattern,\n interceptedRoute: info.interceptedRoute,\n },\n });\n }\n }\n }\n\n // Template edges\n const templates = allFiles.filter((f) => {\n const basename = path.basename(f.path).replace(PAGE_EXTENSIONS, '');\n return f.path.startsWith('app/') && basename === 'template';\n });\n\n for (const template of templates) {\n const templateDir = path.dirname(template.path);\n const templateSymbols = ctx.getSymbolsByFile(template.id);\n const templateSym = templateSymbols.find((s) => s.kind === 'function' || s.kind === 'class');\n if (!templateSym) continue;\n\n // Find pages nested under this template\n for (const page of pages) {\n if (page.path.startsWith(templateDir + '/') || templateDir === 'app') {\n const pageSymbols = ctx.getSymbolsByFile(page.id);\n const pageSym = pageSymbols.find((s) => s.kind === 'function' || s.kind === 'class');\n if (!pageSym) continue;\n\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: templateSym.id,\n targetNodeType: 'symbol',\n targetRefId: pageSym.id,\n edgeType: 'next_template',\n });\n }\n }\n }\n\n // Pages Router data fetching edges\n const pagesRouterFiles = allFiles.filter((f) =>\n f.path.startsWith('pages/') &&\n !f.path.startsWith('pages/api/') &&\n PAGE_EXTENSIONS.test(f.path),\n );\n\n for (const file of pagesRouterFiles) {\n let source: string;\n try {\n source = fs.readFileSync(path.resolve(ctx.rootPath, file.path), 'utf-8');\n } catch { continue; }\n\n const dataFns = extractDataFetchingFunctions(source);\n if (dataFns.length === 0) continue;\n\n const fileSymbols = ctx.getSymbolsByFile(file.id);\n const pageSym = fileSymbols.find((s) => s.kind === 'function' || s.kind === 'class');\n if (!pageSym) continue;\n\n for (const fnName of dataFns) {\n const fnSym = fileSymbols.find((s) => s.kind === 'function' && s.name === fnName);\n if (fnSym) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: pageSym.id,\n targetNodeType: 'symbol',\n targetRefId: fnSym.id,\n edgeType: 'next_data_fetching',\n metadata: { function: fnName },\n });\n }\n }\n }\n\n return ok(edges);\n }\n\n private extractApiMethods(source: string): string[] {\n const methods: string[] = [];\n let match: RegExpExecArray | null;\n const re = new RegExp(API_ROUTE_EXPORTS_RE.source, 'g');\n while ((match = re.exec(source)) !== null) {\n methods.push(match[1]);\n }\n return methods.length > 0 ? methods : ['GET'];\n }\n}\n","/**\n * ExpressPlugin — detects Express.js projects and extracts route registrations,\n * middleware, and router mounts.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\nconst ROUTE_RE =\n /(?:app|router)\\s*\\.\\s*(get|post|put|delete|patch|head|options)\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\nconst MIDDLEWARE_RE =\n /(?:app|router)\\s*\\.\\s*use\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\nconst GLOBAL_MIDDLEWARE_RE =\n /(?:app|router)\\s*\\.\\s*use\\s*\\(\\s*([A-Za-z][\\w.]*(?:\\s*\\(\\s*[^)]*\\))?)\\s*[,)]/g;\n\nexport interface ExpressRoute {\n method: string;\n path: string;\n line?: number;\n}\n\nexport interface ExpressMiddleware {\n path: string;\n isGlobal: boolean;\n name?: string;\n}\n\n/** Extract route registrations from Express source code. */\nexport function extractExpressRoutes(source: string): ExpressRoute[] {\n const routes: ExpressRoute[] = [];\n const re = new RegExp(ROUTE_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n routes.push({\n method: match[1].toUpperCase(),\n path: match[2],\n });\n }\n return routes;\n}\n\n/** Extract middleware use() calls with paths. */\nexport function extractExpressMiddleware(source: string): ExpressMiddleware[] {\n const middlewares: ExpressMiddleware[] = [];\n const pathRe = new RegExp(MIDDLEWARE_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = pathRe.exec(source)) !== null) {\n middlewares.push({ path: match[1], isGlobal: false });\n }\n\n // Global middleware (no path string)\n const globalRe = new RegExp(GLOBAL_MIDDLEWARE_RE.source, 'g');\n while ((match = globalRe.exec(source)) !== null) {\n const name = match[1].trim();\n // Skip if it looks like a path string (already captured above)\n if (/^['\"`]/.test(name)) continue;\n middlewares.push({ path: '/', isGlobal: true, name });\n }\n\n return middlewares;\n}\n\n/** Detect 4-arg error handler middleware: (err, req, res, next) => {} */\nexport function extractErrorHandlers(source: string): { path: string }[] {\n const handlers: { path: string }[] = [];\n // function form\n const funcRe = /(?:app|router)\\s*\\.\\s*use\\s*\\([^;]*?function\\s*\\(\\s*\\w+\\s*,\\s*\\w+\\s*,\\s*\\w+\\s*,\\s*\\w+\\s*\\)/g;\n let m: RegExpExecArray | null;\n while ((m = funcRe.exec(source)) !== null) {\n handlers.push({ path: '/' });\n }\n // arrow form with err/error as first param\n const arrowRe = /(?:app|router)\\s*\\.\\s*use\\s*\\([^;]*?\\(\\s*(?:err|error)\\s*,\\s*\\w+\\s*,\\s*\\w+\\s*,\\s*\\w+\\s*\\)\\s*=>/g;\n while ((m = arrowRe.exec(source)) !== null) {\n handlers.push({ path: '/' });\n }\n return handlers;\n}\n\n/** Extract app.param() handlers */\nexport function extractParamHandlers(source: string): string[] {\n const params: string[] = [];\n const re = /(?:app|router)\\s*\\.\\s*param\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n if (m[1]) params.push(m[1]);\n }\n return params;\n}\n\nexport class ExpressPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'express',\n version: '1.0.0',\n priority: 25,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if ('express' in deps) return true;\n }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n return 'express' in deps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'express_route', category: 'express', description: 'Express route handler' },\n { name: 'express_middleware', category: 'express', description: 'Express middleware' },\n { name: 'express_mounts', category: 'express', description: 'Router mount via app.use' },\n { name: 'express_error_handler', category: 'express', description: '4-arg error handling middleware' },\n { name: 'express_param_handler', category: 'express', description: 'app.param() route parameter handler' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (!['typescript', 'javascript'].includes(language)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = { status: 'ok', symbols: [], routes: [], edges: [] };\n\n const routes = extractExpressRoutes(source);\n if (routes.length > 0) {\n result.frameworkRole = 'express_router';\n for (const route of routes) {\n result.routes!.push({\n method: route.method,\n uri: route.path,\n });\n }\n }\n\n const middlewares = extractExpressMiddleware(source);\n if (middlewares.length > 0) {\n result.frameworkRole = result.frameworkRole ?? 'express_middleware';\n }\n\n const errorHandlers = extractErrorHandlers(source);\n if (errorHandlers.length > 0) {\n result.frameworkRole = result.frameworkRole ?? 'express_error_handler';\n }\n\n const paramHandlers = extractParamHandlers(source);\n if (paramHandlers.length > 0) {\n result.frameworkRole = result.frameworkRole ?? 'express_param_handler';\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n // Express edge resolution is primarily file-level;\n // route -> handler symbol resolution would require call-graph analysis\n // which is beyond the scope of regex-based extraction.\n return ok(edges);\n }\n}\n","/**\n * MongoosePlugin — Framework plugin for Mongoose ODM.\n *\n * Extracts:\n * - Schema definitions (fields, types, options)\n * - Model registrations (mongoose.model)\n * - ObjectId refs → cross-model edges\n * - Virtuals (getter/populate)\n * - Middleware (pre/post hooks)\n * - Methods, statics, query helpers\n * - Plugins, indexes, discriminators\n * - @nestjs/mongoose and Typegoose decorators\n *\n * Supports Mongoose 5.x–8.x.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawOrmModel,\n RawOrmAssociation,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\nimport { escapeRegExp } from '../../../../utils/security.js';\n\nexport class MongoosePlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'mongoose',\n version: '1.0.0',\n priority: 30,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n const deps = {\n ...(ctx.packageJson?.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson?.devDependencies as Record<string, string> | undefined),\n };\n if ('mongoose' in deps) return true;\n\n // Fallback: read package.json from disk\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const json = JSON.parse(content);\n const allDeps = { ...json.dependencies, ...json.devDependencies };\n return 'mongoose' in allDeps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'mongoose_references', category: 'mongoose', description: 'ObjectId ref to another model' },\n { name: 'mongoose_has_virtual', category: 'mongoose', description: 'Schema virtual field' },\n { name: 'mongoose_has_middleware', category: 'mongoose', description: 'Schema pre/post hook' },\n { name: 'mongoose_has_method', category: 'mongoose', description: 'Schema instance method' },\n { name: 'mongoose_has_static', category: 'mongoose', description: 'Schema static method' },\n { name: 'mongoose_discriminates', category: 'mongoose', description: 'Model discriminator' },\n { name: 'mongoose_has_index', category: 'mongoose', description: 'Schema index' },\n { name: 'mongoose_uses_plugin', category: 'mongoose', description: 'Schema plugin' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'typescript' && language !== 'javascript') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n ormModels: [],\n ormAssociations: [],\n warnings: [],\n };\n\n const extraction = extractMongooseSchema(source, filePath);\n if (extraction) {\n result.ormModels = [extraction.model];\n result.ormAssociations = extraction.associations;\n result.frameworkRole = 'mongoose_model';\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n\n// ============================================================\n// Schema extraction\n// ============================================================\n\nexport interface MongooseExtractionResult {\n model: RawOrmModel;\n associations: RawOrmAssociation[];\n}\n\n/**\n * Extract Mongoose schema definition from source file.\n * Detects: new Schema({...}), mongoose.model('Name', schema), @Schema(), @modelOptions()\n */\nexport function extractMongooseSchema(\n source: string,\n filePath: string,\n): MongooseExtractionResult | null {\n // Try plain mongoose first, then decorators\n return extractPlainMongooseSchema(source, filePath)\n ?? extractNestMongooseSchema(source, filePath)\n ?? extractTypegooseSchema(source, filePath);\n}\n\n/**\n * Extract plain mongoose schema: new Schema({...}) + mongoose.model('Name', schema)\n */\nfunction extractPlainMongooseSchema(\n source: string,\n filePath: string,\n): MongooseExtractionResult | null {\n // Match: new mongoose.Schema({...}) or new Schema({...})\n const schemaRegex = /(?:const|let|var)\\s+(\\w+)\\s*=\\s*new\\s+(?:mongoose\\.)?Schema\\s*\\(\\s*\\{([\\s\\S]*?)\\}\\s*(?:,\\s*\\{([\\s\\S]*?)\\})?\\s*\\)/;\n const schemaMatch = source.match(schemaRegex);\n if (!schemaMatch) return null;\n\n const schemaVarName = schemaMatch[1];\n const fieldsBody = schemaMatch[2];\n const optionsBody = schemaMatch[3];\n\n // Find model name: mongoose.model('Name', schema) or model('Name', schema)\n const modelRegex = new RegExp(\n `(?:mongoose\\\\.)?model\\\\s*\\\\(\\\\s*['\"]([^'\"]+)['\"]\\\\s*,\\\\s*${escapeRegExp(schemaVarName)}\\\\s*\\\\)`,\n );\n const modelMatch = source.match(modelRegex);\n const modelName = modelMatch?.[1] ?? schemaVarName.replace(/Schema$/, '');\n\n // Parse fields\n const fields = parseSchemaFields(fieldsBody);\n\n // Parse options\n const options = optionsBody ? parseSchemaOptions(optionsBody) : undefined;\n\n // Extract collection name\n const collectionMatch = optionsBody?.match(/collection\\s*:\\s*['\"]([^'\"]+)['\"]/);\n const collectionName = collectionMatch?.[1];\n\n // Build model\n const model: RawOrmModel = {\n name: modelName,\n orm: 'mongoose',\n collectionOrTable: collectionName,\n fields,\n options,\n metadata: {\n schemaVar: schemaVarName,\n virtuals: extractVirtuals(source, schemaVarName),\n middleware: extractMiddleware(source, schemaVarName),\n methods: extractMethods(source, schemaVarName),\n statics: extractStatics(source, schemaVarName),\n plugins: extractPlugins(source, schemaVarName),\n indexes: extractIndexes(source, schemaVarName),\n discriminators: extractDiscriminators(source, modelName),\n },\n };\n\n // Extract refs as associations\n const associations = extractRefs(fields, modelName);\n\n return { model, associations };\n}\n\n/**\n * Extract @nestjs/mongoose decorated schema.\n * @Schema() class User { @Prop({...}) name: string; }\n */\nfunction extractNestMongooseSchema(\n source: string,\n filePath: string,\n): MongooseExtractionResult | null {\n const classRegex = /@Schema\\s*\\(([^)]*)\\)\\s*export\\s+class\\s+(\\w+)/;\n const classMatch = source.match(classRegex);\n if (!classMatch) return null;\n\n const optionsStr = classMatch[1];\n const className = classMatch[2];\n\n // Extract @Prop() fields\n const fields: Record<string, unknown>[] = [];\n const propRegex = /@Prop\\s*\\(\\s*(?:\\{([\\s\\S]*?)\\})?\\s*\\)\\s*(\\w+)\\s*[?!]?\\s*:\\s*([^;]+)/g;\n let propMatch: RegExpExecArray | null;\n while ((propMatch = propRegex.exec(source)) !== null) {\n const propOptions = propMatch[1] || '';\n const fieldName = propMatch[2];\n const fieldType = propMatch[3].trim();\n fields.push({\n name: fieldName,\n type: fieldType,\n ...parsePropOptions(propOptions),\n });\n }\n\n const collectionMatch = optionsStr?.match(/collection\\s*:\\s*['\"]([^'\"]+)['\"]/);\n\n const model: RawOrmModel = {\n name: className,\n orm: 'mongoose',\n collectionOrTable: collectionMatch?.[1],\n fields,\n metadata: { style: 'nestjs-mongoose' },\n };\n\n const associations = extractRefs(fields, className);\n return { model, associations };\n}\n\n/**\n * Extract Typegoose decorated schema.\n * @modelOptions({...}) class User { @prop({...}) public name!: string; }\n */\nfunction extractTypegooseSchema(\n source: string,\n filePath: string,\n): MongooseExtractionResult | null {\n const classRegex = /@modelOptions\\s*\\(\\s*\\{([\\s\\S]*?)\\}\\s*\\)\\s*export\\s+class\\s+(\\w+)/;\n const classMatch = source.match(classRegex);\n if (!classMatch) return null;\n\n const optionsStr = classMatch[1];\n const className = classMatch[2];\n\n // Extract @prop() fields\n const fields: Record<string, unknown>[] = [];\n const propRegex = /@prop\\s*\\(\\s*(?:\\{([\\s\\S]*?)\\})?\\s*\\)\\s*public\\s+(\\w+)\\s*[?!]?\\s*:\\s*([^;]+)/g;\n let propMatch: RegExpExecArray | null;\n while ((propMatch = propRegex.exec(source)) !== null) {\n const propOptions = propMatch[1] || '';\n const fieldName = propMatch[2];\n const fieldType = propMatch[3].trim();\n fields.push({\n name: fieldName,\n type: fieldType,\n ...parsePropOptions(propOptions),\n });\n }\n\n const collectionMatch = optionsStr?.match(/collection\\s*:\\s*['\"]([^'\"]+)['\"]/);\n\n const model: RawOrmModel = {\n name: className,\n orm: 'mongoose',\n collectionOrTable: collectionMatch?.[1],\n fields,\n metadata: { style: 'typegoose' },\n };\n\n const associations = extractRefs(fields, className);\n return { model, associations };\n}\n\n// ============================================================\n// Field parsing\n// ============================================================\n\nfunction parseSchemaFields(body: string): Record<string, unknown>[] {\n const fields: Record<string, unknown>[] = [];\n\n // Match top-level field definitions:\n // name: { type: String, ... }\n // name: String\n // name: [{ type: ObjectId, ref: 'Post' }] (array)\n const fieldRegex = /(\\w+)\\s*:\\s*(?:\\[\\s*\\{([^{}]*(?:\\{[^{}]*\\}[^{}]*)*)\\}\\s*\\]|\\{([^{}]*(?:\\{[^{}]*\\}[^{}]*)*)\\}|(\\w[\\w.]*(?:\\.\\w+)*)(?:\\s*,)?)/g;\n let match: RegExpExecArray | null;\n while ((match = fieldRegex.exec(body)) !== null) {\n const fieldName = match[1];\n // Skip common non-field names\n if (['type', 'ref', 'required', 'default', 'enum', 'unique', 'index', 'select', 'validate'].includes(fieldName)) continue;\n\n if (match[2]) {\n // Array of objects form: [{ type: ObjectId, ref: 'Post' }]\n const fieldBody = match[2];\n const field: Record<string, unknown> = { name: fieldName, isArray: true };\n\n const typeMatch = fieldBody.match(/type\\s*:\\s*([\\w.]+(?:\\.\\w+)*)/);\n if (typeMatch) field.type = typeMatch[1];\n\n const refMatch = fieldBody.match(/ref\\s*:\\s*['\"]([^'\"]+)['\"]/);\n if (refMatch) field.ref = refMatch[1];\n\n if (/required\\s*:\\s*true/.test(fieldBody)) field.required = true;\n\n fields.push(field);\n } else if (match[3]) {\n // Object form: { type: String, required: true, ... }\n const fieldBody = match[3];\n const field: Record<string, unknown> = { name: fieldName };\n\n const typeMatch = fieldBody.match(/type\\s*:\\s*([\\w.]+(?:\\.\\w+)*)/);\n if (typeMatch) field.type = typeMatch[1];\n\n const refMatch = fieldBody.match(/ref\\s*:\\s*['\"]([^'\"]+)['\"]/);\n if (refMatch) field.ref = refMatch[1];\n\n if (/required\\s*:\\s*true/.test(fieldBody)) field.required = true;\n if (/unique\\s*:\\s*true/.test(fieldBody)) field.unique = true;\n if (/index\\s*:\\s*true/.test(fieldBody)) field.index = true;\n\n const enumMatch = fieldBody.match(/enum\\s*:\\s*\\[([^\\]]+)\\]/);\n if (enumMatch) {\n const enumValues: string[] = [];\n const valRegex = /['\"]([^'\"]+)['\"]/g;\n let vm: RegExpExecArray | null;\n while ((vm = valRegex.exec(enumMatch[1])) !== null) {\n enumValues.push(vm[1]);\n }\n field.enum = enumValues;\n }\n\n const defaultMatch = fieldBody.match(/default\\s*:\\s*['\"]?([^'\",}\\s]+)['\"]?/);\n if (defaultMatch) field.default = defaultMatch[1];\n\n fields.push(field);\n } else if (match[3]) {\n // Shorthand form: name: String\n fields.push({ name: fieldName, type: match[3] });\n }\n }\n\n return fields;\n}\n\nfunction parseSchemaOptions(body: string): Record<string, unknown> {\n const options: Record<string, unknown> = {};\n if (/timestamps\\s*:\\s*true/.test(body)) options.timestamps = true;\n if (/collection\\s*:\\s*['\"]([^'\"]+)['\"]/.test(body)) {\n options.collection = body.match(/collection\\s*:\\s*['\"]([^'\"]+)['\"]/)?.[1];\n }\n if (/versionKey\\s*:\\s*false/.test(body)) options.versionKey = false;\n if (/strict\\s*:\\s*false/.test(body)) options.strict = false;\n return options;\n}\n\nfunction parsePropOptions(body: string): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n if (/required\\s*:\\s*true/.test(body)) result.required = true;\n if (/unique\\s*:\\s*true/.test(body)) result.unique = true;\n\n const refMatch = body.match(/ref\\s*:\\s*(?:['\"]([^'\"]+)['\"]|(?:\\(\\)\\s*=>\\s*)?(\\w+))/);\n if (refMatch) result.ref = refMatch[1] ?? refMatch[2];\n\n const typeMatch = body.match(/type\\s*:\\s*([\\w.]+)/);\n if (typeMatch) result.mongooseType = typeMatch[1];\n\n return result;\n}\n\n// ============================================================\n// Metadata extraction (virtuals, middleware, methods, etc.)\n// ============================================================\n\nfunction extractVirtuals(source: string, schemaVar: string): string[] {\n const virtuals: string[] = [];\n const regex = new RegExp(`${escapeRegExp(schemaVar)}\\\\.virtual\\\\s*\\\\(\\\\s*['\"]([^'\"]+)['\"]`, 'g');\n let m: RegExpExecArray | null;\n while ((m = regex.exec(source)) !== null) {\n virtuals.push(m[1]);\n }\n return virtuals;\n}\n\nfunction extractMiddleware(source: string, schemaVar: string): Array<{ hook: string; event: string }> {\n const middleware: Array<{ hook: string; event: string }> = [];\n const regex = new RegExp(`${escapeRegExp(schemaVar)}\\\\.(pre|post)\\\\s*\\\\(\\\\s*['\"]([^'\"]+)['\"]`, 'g');\n let m: RegExpExecArray | null;\n while ((m = regex.exec(source)) !== null) {\n middleware.push({ hook: m[1], event: m[2] });\n }\n return middleware;\n}\n\nfunction extractMethods(source: string, schemaVar: string): string[] {\n const methods: string[] = [];\n const regex = new RegExp(`${escapeRegExp(schemaVar)}\\\\.methods\\\\.(\\\\w+)`, 'g');\n let m: RegExpExecArray | null;\n while ((m = regex.exec(source)) !== null) {\n methods.push(m[1]);\n }\n return methods;\n}\n\nfunction extractStatics(source: string, schemaVar: string): string[] {\n const statics: string[] = [];\n const regex = new RegExp(`${escapeRegExp(schemaVar)}\\\\.statics\\\\.(\\\\w+)`, 'g');\n let m: RegExpExecArray | null;\n while ((m = regex.exec(source)) !== null) {\n statics.push(m[1]);\n }\n return statics;\n}\n\nfunction extractPlugins(source: string, schemaVar: string): string[] {\n const plugins: string[] = [];\n const regex = new RegExp(`${escapeRegExp(schemaVar)}\\\\.plugin\\\\s*\\\\(\\\\s*(\\\\w+)`, 'g');\n let m: RegExpExecArray | null;\n while ((m = regex.exec(source)) !== null) {\n plugins.push(m[1]);\n }\n return plugins;\n}\n\nfunction extractIndexes(source: string, schemaVar: string): string[] {\n const indexes: string[] = [];\n const regex = new RegExp(`${escapeRegExp(schemaVar)}\\\\.index\\\\s*\\\\(\\\\s*\\\\{([^}]+)\\\\}`, 'g');\n let m: RegExpExecArray | null;\n while ((m = regex.exec(source)) !== null) {\n indexes.push(m[1].trim());\n }\n return indexes;\n}\n\nfunction extractDiscriminators(source: string, modelName: string): string[] {\n const discriminators: string[] = [];\n const regex = new RegExp(`${escapeRegExp(modelName)}\\\\.discriminator\\\\s*\\\\(\\\\s*['\"]([^'\"]+)['\"]`, 'g');\n let m: RegExpExecArray | null;\n while ((m = regex.exec(source)) !== null) {\n discriminators.push(m[1]);\n }\n return discriminators;\n}\n\n/**\n * Extract ref associations from parsed fields.\n */\nfunction extractRefs(\n fields: Record<string, unknown>[],\n sourceModelName: string,\n): RawOrmAssociation[] {\n const associations: RawOrmAssociation[] = [];\n for (const field of fields) {\n if (field.ref && typeof field.ref === 'string') {\n associations.push({\n sourceModelName,\n targetModelName: field.ref as string,\n kind: 'ref',\n options: { field: field.name },\n });\n }\n }\n return associations;\n}\n","/**\n * SequelizePlugin — Framework plugin for Sequelize ORM.\n *\n * Extracts:\n * - Model definitions (Model.init, sequelize.define, decorators)\n * - Associations (hasMany, belongsTo, belongsToMany, hasOne)\n * - Migrations (queryInterface.createTable/addColumn/etc.)\n * - Hooks (beforeCreate, afterUpdate, etc.)\n * - Scopes\n *\n * Supports Sequelize 4.x–7.x and sequelize-typescript.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawOrmModel,\n RawOrmAssociation,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\n\nexport class SequelizePlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'sequelize',\n version: '1.0.0',\n priority: 30,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n const deps = {\n ...(ctx.packageJson?.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson?.devDependencies as Record<string, string> | undefined),\n };\n if ('sequelize' in deps || 'sequelize-typescript' in deps) return true;\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const json = JSON.parse(content);\n const allDeps = { ...json.dependencies, ...json.devDependencies };\n return 'sequelize' in allDeps || 'sequelize-typescript' in allDeps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'sequelize_has_many', category: 'sequelize', description: 'Sequelize hasMany association' },\n { name: 'sequelize_belongs_to', category: 'sequelize', description: 'Sequelize belongsTo association' },\n { name: 'sequelize_belongs_to_many', category: 'sequelize', description: 'Sequelize belongsToMany association' },\n { name: 'sequelize_has_one', category: 'sequelize', description: 'Sequelize hasOne association' },\n { name: 'sequelize_has_hook', category: 'sequelize', description: 'Sequelize lifecycle hook' },\n { name: 'sequelize_has_scope', category: 'sequelize', description: 'Sequelize named scope' },\n { name: 'sequelize_migrates', category: 'sequelize', description: 'Migration changes table schema' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'typescript' && language !== 'javascript') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n ormModels: [],\n ormAssociations: [],\n warnings: [],\n };\n\n // Model extraction\n const modelExtraction = extractSequelizeModel(source, filePath);\n if (modelExtraction) {\n result.ormModels = [modelExtraction.model];\n result.ormAssociations = modelExtraction.associations;\n result.frameworkRole = 'sequelize_model';\n }\n\n // Migration extraction\n if (this.isMigrationFile(filePath)) {\n const migExtraction = extractSequelizeMigration(source, filePath);\n if (migExtraction) {\n result.ormModels = migExtraction.models;\n result.frameworkRole = 'sequelize_migration';\n }\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n\n private isMigrationFile(filePath: string): boolean {\n return /migrations?\\//.test(filePath) && /\\d/.test(path.basename(filePath));\n }\n}\n\n// ============================================================\n// Model extraction\n// ============================================================\n\nexport interface SequelizeModelResult {\n model: RawOrmModel;\n associations: RawOrmAssociation[];\n}\n\n/**\n * Extract Sequelize model from source.\n * Handles: class-based (v6+), define() (v4-5), sequelize-typescript decorators.\n */\nexport function extractSequelizeModel(\n source: string,\n filePath: string,\n): SequelizeModelResult | null {\n return extractClassModel(source, filePath)\n ?? extractDefineModel(source, filePath)\n ?? extractDecoratorModel(source, filePath);\n}\n\n/**\n * v6+ class-based: class User extends Model { } User.init({...}, {...})\n */\nfunction extractClassModel(\n source: string,\n filePath: string,\n): SequelizeModelResult | null {\n const classRegex = /class\\s+(\\w+)\\s+extends\\s+Model\\s*\\{/;\n const classMatch = source.match(classRegex);\n if (!classMatch) return null;\n\n const className = classMatch[1];\n\n // Extract Model.init({fields}, {options}) — required for class-based Sequelize model\n const initRegex = new RegExp(\n `${className}\\\\.init\\\\s*\\\\(\\\\s*\\\\{([\\\\s\\\\S]*?)\\\\}\\\\s*,\\\\s*\\\\{([\\\\s\\\\S]*?)\\\\}\\\\s*\\\\)`,\n );\n const initMatch = source.match(initRegex);\n\n // Require Model.init() or DataTypes usage — distinguish from sequelize-typescript decorators\n if (!initMatch && !/\\bDataTypes\\b/.test(source)) return null;\n\n const fields = initMatch ? parseSequelizeFields(initMatch[1]) : [];\n const options = initMatch ? parseSequelizeOptions(initMatch[2]) : {};\n\n // Extract associations from static associate(models) method\n const associations = extractAssociations(source, className);\n\n // Extract hooks\n const hooks = extractHooks(source, className);\n\n // Extract scopes\n const scopes = extractScopes(source, className);\n\n const model: RawOrmModel = {\n name: className,\n orm: 'sequelize',\n collectionOrTable: (options as Record<string, unknown>).tableName as string | undefined,\n fields,\n options,\n metadata: {\n hooks,\n scopes,\n style: 'class-based',\n },\n };\n\n return { model, associations };\n}\n\n/**\n * v4-5 define: sequelize.define('User', {fields}, {options})\n */\nfunction extractDefineModel(\n source: string,\n filePath: string,\n): SequelizeModelResult | null {\n const defineRegex = /sequelize\\.define\\s*\\(\\s*['\"](\\w+)['\"]\\s*,\\s*\\{([\\s\\S]*?)\\}\\s*(?:,\\s*\\{([\\s\\S]*?)\\})?\\s*\\)/;\n const match = source.match(defineRegex);\n if (!match) return null;\n\n const modelName = match[1];\n const fields = parseSequelizeFields(match[2]);\n const options = match[3] ? parseSequelizeOptions(match[3]) : {};\n\n // Try to extract associations from classMethods or separate associate calls\n const associations = extractAssociations(source, modelName);\n\n const model: RawOrmModel = {\n name: modelName,\n orm: 'sequelize',\n fields,\n options,\n metadata: { style: 'define' },\n };\n\n return { model, associations };\n}\n\n/**\n * sequelize-typescript decorators: @Table class User extends Model { @Column name: string; }\n */\nfunction extractDecoratorModel(\n source: string,\n filePath: string,\n): SequelizeModelResult | null {\n const classRegex = /@Table\\s*(?:\\(\\s*\\{([\\s\\S]*?)\\}\\s*\\))?\\s+export\\s+class\\s+(\\w+)\\s+extends\\s+Model/;\n const classMatch = source.match(classRegex);\n if (!classMatch) return null;\n\n const optionsStr = classMatch[1] || '';\n const className = classMatch[2];\n\n // Extract @Column fields\n const fields: Record<string, unknown>[] = [];\n const colRegex = /@Column\\s*(?:\\(\\s*\\{([\\s\\S]*?)\\}\\s*\\))?\\s*(\\w+)\\s*[?!]?\\s*:\\s*(\\w+)/g;\n let colMatch: RegExpExecArray | null;\n while ((colMatch = colRegex.exec(source)) !== null) {\n const colOptions = colMatch[1] || '';\n fields.push({\n name: colMatch[2],\n type: colMatch[3],\n ...parseColumnOptions(colOptions),\n });\n }\n\n // Extract decorator-based associations: @HasMany(() => Post), @BelongsTo(() => Role)\n const associations = extractDecoratorAssociations(source, className);\n\n const tableNameMatch = optionsStr.match(/tableName\\s*:\\s*['\"]([^'\"]+)['\"]/);\n const paranoidMatch = /paranoid\\s*:\\s*true/.test(optionsStr);\n\n const model: RawOrmModel = {\n name: className,\n orm: 'sequelize',\n collectionOrTable: tableNameMatch?.[1],\n fields,\n options: { ...(paranoidMatch ? { paranoid: true } : {}) },\n metadata: { style: 'sequelize-typescript' },\n };\n\n return { model, associations };\n}\n\n// ============================================================\n// Migration extraction\n// ============================================================\n\ninterface MigrationResult {\n models: RawOrmModel[];\n}\n\nexport function extractSequelizeMigration(\n source: string,\n filePath: string,\n): MigrationResult | null {\n const models: RawOrmModel[] = [];\n\n // Match queryInterface.createTable('name', { ... })\n const createRegex = /queryInterface\\.createTable\\s*\\(\\s*['\"](\\w+)['\"]\\s*,\\s*\\{([\\s\\S]*?)\\}\\s*\\)/g;\n let match: RegExpExecArray | null;\n while ((match = createRegex.exec(source)) !== null) {\n const tableName = match[1];\n const fields = parseMigrationFields(match[2]);\n models.push({\n name: tableName,\n orm: 'sequelize',\n collectionOrTable: tableName,\n fields,\n metadata: { source: 'migration', operation: 'createTable' },\n });\n }\n\n // Match queryInterface.addColumn('table', 'column', { ... })\n const addColRegex = /queryInterface\\.addColumn\\s*\\(\\s*['\"](\\w+)['\"]\\s*,\\s*['\"](\\w+)['\"]\\s*,\\s*\\{([\\s\\S]*?)\\}\\s*\\)/g;\n while ((match = addColRegex.exec(source)) !== null) {\n models.push({\n name: match[1],\n orm: 'sequelize',\n collectionOrTable: match[1],\n fields: [parseColumnDef(match[2], match[3])],\n metadata: { source: 'migration', operation: 'addColumn' },\n });\n }\n\n return models.length > 0 ? { models } : null;\n}\n\n// ============================================================\n// Field parsing helpers\n// ============================================================\n\nfunction parseSequelizeFields(body: string): Record<string, unknown>[] {\n const fields: Record<string, unknown>[] = [];\n // Match: fieldName: { type: DataTypes.STRING, ... } or fieldName: DataTypes.STRING\n const fieldRegex = /(\\w+)\\s*:\\s*(?:\\{([^{}]*(?:\\{[^{}]*\\}[^{}]*)*)\\}|DataTypes\\.(\\w+)|(Sequelize\\.(\\w+)))/g;\n let match: RegExpExecArray | null;\n while ((match = fieldRegex.exec(body)) !== null) {\n const name = match[1];\n if (['type', 'references', 'key', 'model'].includes(name)) continue;\n\n if (match[2]) {\n // Object form\n const fieldBody = match[2];\n const field: Record<string, unknown> = { name };\n\n const typeMatch = fieldBody.match(/type\\s*:\\s*(?:DataTypes|Sequelize)\\.(\\w+)/);\n if (typeMatch) field.type = typeMatch[1];\n\n if (/allowNull\\s*:\\s*false/.test(fieldBody)) field.allowNull = false;\n if (/unique\\s*:\\s*true/.test(fieldBody)) field.unique = true;\n if (/primaryKey\\s*:\\s*true/.test(fieldBody)) field.primaryKey = true;\n if (/autoIncrement\\s*:\\s*true/.test(fieldBody)) field.autoIncrement = true;\n\n // Foreign key references\n const refMatch = fieldBody.match(/references\\s*:\\s*\\{\\s*model\\s*:\\s*['\"](\\w+)['\"].*?\\}/);\n if (refMatch) field.references = refMatch[1];\n\n // Validate\n const validateMatch = fieldBody.match(/validate\\s*:\\s*\\{([^}]+)\\}/);\n if (validateMatch) {\n const validators: string[] = [];\n const valRegex = /(\\w+)\\s*:/g;\n let vm: RegExpExecArray | null;\n while ((vm = valRegex.exec(validateMatch[1])) !== null) {\n validators.push(vm[1]);\n }\n field.validate = validators;\n }\n\n fields.push(field);\n } else {\n // Shorthand: DataTypes.STRING\n fields.push({ name, type: match[3] || match[5] });\n }\n }\n return fields;\n}\n\nfunction parseSequelizeOptions(body: string): Record<string, unknown> {\n const options: Record<string, unknown> = {};\n const tableNameMatch = body.match(/tableName\\s*:\\s*['\"]([^'\"]+)['\"]/);\n if (tableNameMatch) options.tableName = tableNameMatch[1];\n if (/paranoid\\s*:\\s*true/.test(body)) options.paranoid = true;\n if (/timestamps\\s*:\\s*true/.test(body)) options.timestamps = true;\n if (/timestamps\\s*:\\s*false/.test(body)) options.timestamps = false;\n return options;\n}\n\nfunction parseColumnOptions(body: string): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const typeMatch = body.match(/type\\s*:\\s*DataType\\.(\\w+)/);\n if (typeMatch) result.dataType = typeMatch[1];\n if (/allowNull\\s*:\\s*false/.test(body)) result.allowNull = false;\n return result;\n}\n\nfunction parseMigrationFields(body: string): Record<string, unknown>[] {\n const fields: Record<string, unknown>[] = [];\n const fieldRegex = /(\\w+)\\s*:\\s*\\{([^{}]*(?:\\{[^{}]*\\}[^{}]*)*)\\}/g;\n let match: RegExpExecArray | null;\n while ((match = fieldRegex.exec(body)) !== null) {\n fields.push(parseColumnDef(match[1], match[2]));\n }\n return fields;\n}\n\nfunction parseColumnDef(name: string, body: string): Record<string, unknown> {\n const field: Record<string, unknown> = { name };\n const typeMatch = body.match(/type\\s*:\\s*(?:Sequelize|DataTypes)\\.(\\w+)/);\n if (typeMatch) field.type = typeMatch[1];\n if (/primaryKey\\s*:\\s*true/.test(body)) field.primaryKey = true;\n if (/autoIncrement\\s*:\\s*true/.test(body)) field.autoIncrement = true;\n if (/allowNull\\s*:\\s*false/.test(body)) field.allowNull = false;\n\n const refMatch = body.match(/references\\s*:\\s*\\{\\s*model\\s*:\\s*['\"](\\w+)['\"]/);\n if (refMatch) field.references = refMatch[1];\n\n return field;\n}\n\n// ============================================================\n// Association extraction\n// ============================================================\n\nconst ASSOCIATION_MAP: Record<string, string> = {\n hasMany: 'sequelize_has_many',\n belongsTo: 'sequelize_belongs_to',\n belongsToMany: 'sequelize_belongs_to_many',\n hasOne: 'sequelize_has_one',\n};\n\nfunction extractAssociations(\n source: string,\n className: string,\n): RawOrmAssociation[] {\n const associations: RawOrmAssociation[] = [];\n\n // Match: ClassName.hasMany(models.Post, { ... }) or this.hasMany(Post, { ... })\n const regex = new RegExp(\n `(?:${className}|this)\\\\.(hasMany|belongsTo|belongsToMany|hasOne)\\\\s*\\\\(\\\\s*(?:models\\\\.)?(\\\\w+)(?:\\\\.\\\\w+)?\\\\s*(?:,\\\\s*\\\\{([^}]*)\\\\})?`,\n 'g',\n );\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const assocType = match[1];\n const targetModel = match[2];\n const optionsStr = match[3] || '';\n\n const options: Record<string, unknown> = {};\n const fkMatch = optionsStr.match(/foreignKey\\s*:\\s*['\"](\\w+)['\"]/);\n if (fkMatch) options.foreignKey = fkMatch[1];\n const asMatch = optionsStr.match(/as\\s*:\\s*['\"](\\w+)['\"]/);\n if (asMatch) options.as = asMatch[1];\n const throughMatch = optionsStr.match(/through\\s*:\\s*['\"](\\w+)['\"]/);\n if (throughMatch) options.through = throughMatch[1];\n\n associations.push({\n sourceModelName: className,\n targetModelName: targetModel,\n kind: assocType,\n options: Object.keys(options).length > 0 ? options : undefined,\n });\n }\n\n return associations;\n}\n\nfunction extractDecoratorAssociations(\n source: string,\n className: string,\n): RawOrmAssociation[] {\n const associations: RawOrmAssociation[] = [];\n\n // Match: @HasMany(() => Post), @BelongsTo(() => Role), etc.\n const regex = /@(HasMany|BelongsTo|BelongsToMany|HasOne)\\s*\\(\\s*\\(\\)\\s*=>\\s*(\\w+)\\s*\\)/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n const decoratorMap: Record<string, string> = {\n HasMany: 'hasMany',\n BelongsTo: 'belongsTo',\n BelongsToMany: 'belongsToMany',\n HasOne: 'hasOne',\n };\n associations.push({\n sourceModelName: className,\n targetModelName: match[2],\n kind: decoratorMap[match[1]] ?? match[1],\n });\n }\n\n return associations;\n}\n\n// ============================================================\n// Hooks and scopes\n// ============================================================\n\nfunction extractHooks(source: string, className: string): string[] {\n const hooks: string[] = [];\n const regex = new RegExp(\n `${className}\\\\.(before|after)(Create|Update|Destroy|Find|Validate|Save|Sync|BulkCreate|BulkUpdate|BulkDestroy)`,\n 'g',\n );\n let m: RegExpExecArray | null;\n while ((m = regex.exec(source)) !== null) {\n hooks.push(`${m[1]}${m[2]}`);\n }\n\n // Also match addHook pattern\n const hookRegex = new RegExp(\n `${className}\\\\.addHook\\\\s*\\\\(\\\\s*['\"]([^'\"]+)['\"]`,\n 'g',\n );\n while ((m = hookRegex.exec(source)) !== null) {\n hooks.push(m[1]);\n }\n\n return hooks;\n}\n\nfunction extractScopes(source: string, className: string): string[] {\n const scopes: string[] = [];\n // Match scopes in options: scopes: { active: { ... }, ... }\n const scopeBlockRegex = /scopes\\s*:\\s*\\{([\\s\\S]*?)\\}/;\n const blockMatch = source.match(scopeBlockRegex);\n if (blockMatch) {\n const scopeRegex = /(\\w+)\\s*:\\s*\\{/g;\n let m: RegExpExecArray | null;\n while ((m = scopeRegex.exec(blockMatch[1])) !== null) {\n scopes.push(m[1]);\n }\n }\n\n // Also match addScope pattern\n const addScopeRegex = new RegExp(\n `${className}\\\\.addScope\\\\s*\\\\(\\\\s*['\"]([^'\"]+)['\"]`,\n 'g',\n );\n let m: RegExpExecArray | null;\n while ((m = addScopeRegex.exec(source)) !== null) {\n scopes.push(m[1]);\n }\n\n return scopes;\n}\n","/**\n * ReactNativePlugin — Framework plugin for React Native applications.\n *\n * Extracts:\n * - React Navigation graph (v3-v6): screens, navigators, nesting\n * - navigation.navigate() → screen edges\n * - Deep linking configuration\n * - Platform-specific files (.ios.tsx, .android.tsx)\n * - NativeModules / TurboModuleRegistry usage\n * - Expo Router file-based routing\n *\n * Supports RN 0.50+ and React Navigation v3-v6.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRnScreen,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\n\n/** Map an Expo Router app/ file path to a route string. Returns null if not in app/ dir. */\nexport function expoFileToRoute(filePath: string): { route: string; isLayout: boolean; is404: boolean } | null {\n // Normalize to forward slashes\n const normalized = filePath.replace(/\\\\/g, '/');\n const match = normalized.match(/(?:^|\\/)app\\/(.+)\\.(tsx?|jsx?)$/);\n if (!match) return null;\n\n let routePart = match[1];\n const isLayout = routePart.endsWith('_layout') || routePart === '_layout';\n const is404 = routePart.includes('+not-found');\n\n // Remove route groups: (tabs)/ → (keep for grouping but don't add to path)\n routePart = routePart.replace(/\\([^)]+\\)\\//g, '');\n // Dynamic segments: [id] → :id, [...slug] → *\n routePart = routePart.replace(/\\[\\.\\.\\.([^\\]]+)\\]/g, '*');\n routePart = routePart.replace(/\\[([^\\]]+)\\]/g, ':$1');\n // Remove _layout suffix\n routePart = routePart.replace(/_layout$/, '');\n // index → empty\n routePart = routePart.replace(/\\/index$|^index$/, '');\n\n const route = '/' + routePart.replace(/\\/+/g, '/').replace(/^\\/+|\\/+$/g, '');\n return { route: route || '/', isLayout, is404 };\n}\n\nexport class ReactNativePlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'react-native',\n version: '1.0.0',\n priority: 20,\n dependencies: [],\n };\n\n private hasExpoRouter = false;\n\n detect(ctx: ProjectContext): boolean {\n const deps = {\n ...(ctx.packageJson?.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson?.devDependencies as Record<string, string> | undefined),\n };\n if ('react-native' in deps) {\n if ('expo-router' in deps) {\n this.hasExpoRouter = true;\n }\n return true;\n }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const json = JSON.parse(content);\n const allDeps = { ...json.dependencies, ...json.devDependencies };\n if ('expo-router' in allDeps) this.hasExpoRouter = true;\n return 'react-native' in allDeps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'rn_navigates_to', category: 'react-native', description: 'navigation.navigate() to screen' },\n { name: 'rn_screen_in_navigator', category: 'react-native', description: 'Screen registered in navigator' },\n { name: 'rn_uses_native_module', category: 'react-native', description: 'Uses NativeModules/TurboModuleRegistry' },\n { name: 'rn_platform_specific', category: 'react-native', description: 'Platform-specific file variant' },\n { name: 'rn_deep_links_to', category: 'react-native', description: 'Deep link maps to screen' },\n { name: 'expo_route', category: 'expo-router', description: 'Expo Router file-based route' },\n { name: 'expo_layout', category: 'expo-router', description: 'Expo Router layout file' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'typescript' && language !== 'javascript') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n rnScreens: [],\n warnings: [],\n };\n\n // Expo Router: file-based routing from app/ directory\n if (this.hasExpoRouter) {\n const expoRoute = expoFileToRoute(filePath);\n if (expoRoute && !expoRoute.is404) {\n if (expoRoute.isLayout) {\n result.frameworkRole = 'expo_layout';\n } else {\n // Navigation calls in this screen\n const navCalls = extractNavigationCalls(source);\n result.rnScreens = [{\n name: expoRoute.route,\n componentPath: filePath,\n navigatorType: 'native-stack',\n deepLink: expoRoute.route,\n metadata: {\n expoRoute: true,\n navigationCalls: navCalls,\n nativeModules: hasNativeModuleUsage(source) ? extractNativeModuleNames(source) : [],\n },\n }];\n result.frameworkRole = 'expo_route';\n }\n return ok(result);\n }\n }\n\n // Extract screens from navigator definitions\n const screens = extractNavigatorScreens(source, filePath);\n if (screens.length > 0) {\n result.rnScreens = screens;\n result.frameworkRole = 'rn_navigator';\n }\n\n // Detect platform-specific file\n if (isPlatformSpecificFile(filePath)) {\n result.frameworkRole = 'rn_platform_specific';\n }\n\n // Detect native module usage\n if (hasNativeModuleUsage(source)) {\n result.frameworkRole = result.frameworkRole ?? 'rn_native_bridge';\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n const allFiles = ctx.getAllFiles();\n\n // Build screen-name → file ID map, and collect navigation calls per file\n const screenNameToFileId = new Map<string, number>();\n const fileNavCalls = new Map<number, string[]>();\n const fileExpoNavCalls = new Map<number, string[]>();\n\n for (const file of allFiles) {\n if (file.language !== 'typescript' && file.language !== 'javascript') continue;\n\n const source = ctx.readFile(file.path);\n if (!source) continue;\n\n // Screens defined in this file (navigator JSX)\n const screens = extractNavigatorScreens(source, file.path);\n for (const s of screens) {\n screenNameToFileId.set(s.name, file.id);\n }\n\n // Expo Router file-based screens\n if (this.hasExpoRouter) {\n const expoRoute = expoFileToRoute(file.path);\n if (expoRoute && !expoRoute.is404 && !expoRoute.isLayout) {\n screenNameToFileId.set(expoRoute.route, file.id);\n }\n }\n\n // React Navigation calls (screen-name based)\n const navCalls = extractNavigationCalls(source);\n if (navCalls.length > 0) {\n fileNavCalls.set(file.id, navCalls);\n }\n\n // Expo Router calls (path-based)\n if (this.hasExpoRouter) {\n const expoCalls = extractExpoNavigationCalls(source);\n if (expoCalls.length > 0) {\n const existing = fileExpoNavCalls.get(file.id) ?? [];\n existing.push(...expoCalls);\n fileExpoNavCalls.set(file.id, existing);\n }\n }\n }\n\n // Create rn_navigates_to edges from React Navigation calls (name-based)\n for (const [sourceFileId, calls] of fileNavCalls) {\n for (const targetName of calls) {\n const targetFileId = screenNameToFileId.get(targetName);\n if (targetFileId == null) continue;\n\n edges.push({\n sourceNodeType: 'file',\n sourceRefId: sourceFileId,\n targetNodeType: 'file',\n targetRefId: targetFileId,\n edgeType: 'rn_navigates_to',\n metadata: { targetScreen: targetName },\n });\n }\n }\n\n // Create rn_navigates_to edges from Expo Router calls (path-based)\n const routePatterns = Array.from(screenNameToFileId.keys());\n for (const [sourceFileId, paths] of fileExpoNavCalls) {\n for (const navPath of paths) {\n // Try exact match first, then pattern match\n let targetFileId = screenNameToFileId.get(navPath);\n if (targetFileId == null) {\n const matched = routePatterns.find((rp) => matchExpoRoute(navPath, rp));\n if (matched) targetFileId = screenNameToFileId.get(matched);\n }\n if (targetFileId == null) continue;\n\n edges.push({\n sourceNodeType: 'file',\n sourceRefId: sourceFileId,\n targetNodeType: 'file',\n targetRefId: targetFileId,\n edgeType: 'rn_navigates_to',\n metadata: { targetScreen: navPath, expoRouter: true },\n });\n }\n }\n\n // Create rn_platform_specific edges: Button.ios.tsx → Button.tsx (base file)\n const filePathToId = new Map<string, number>();\n for (const file of allFiles) {\n filePathToId.set(file.path, file.id);\n }\n\n for (const file of allFiles) {\n if (!isPlatformSpecificFile(file.path)) continue;\n const platform = getPlatform(file.path);\n if (!platform) continue;\n\n // Strip platform suffix: Button.ios.tsx → Button.tsx\n const basePath = file.path.replace(`.${platform}.`, '.');\n const baseFileId = filePathToId.get(basePath);\n if (baseFileId == null) continue;\n\n edges.push({\n sourceNodeType: 'file',\n sourceRefId: file.id,\n targetNodeType: 'file',\n targetRefId: baseFileId,\n edgeType: 'rn_platform_specific',\n metadata: { platform },\n });\n }\n\n return ok(edges);\n }\n}\n\n// ============================================================\n// Navigator screen extraction\n// ============================================================\n\n/**\n * Extract screens from React Navigation navigator definitions.\n * Handles v6, v5, v4, and v3 patterns.\n */\nexport function extractNavigatorScreens(\n source: string,\n filePath: string,\n): RawRnScreen[] {\n const screens: RawRnScreen[] = [];\n\n // Detect navigator type from creation call\n const navigatorType = detectNavigatorType(source);\n\n // v5-v6 JSX: <Stack.Screen name=\"Home\" component={HomeScreen} />\n const jsxScreenRegex = /<(\\w+)\\.Screen\\s+([^>]*?)\\/>/g;\n let match: RegExpExecArray | null;\n while ((match = jsxScreenRegex.exec(source)) !== null) {\n const attrs = match[2];\n const nameMatch = attrs.match(/name\\s*=\\s*[\"']([^\"']+)[\"']/);\n const componentMatch = attrs.match(/component\\s*=\\s*\\{(\\w+)\\}/);\n\n if (nameMatch) {\n screens.push({\n name: nameMatch[1],\n componentPath: componentMatch?.[1],\n navigatorType: navigatorType ?? 'stack',\n });\n }\n }\n\n // v4 object syntax: createStackNavigator({ Home: { screen: HomeScreen }, ... })\n const v4StartRegex = /create(?:Stack|Tab|Drawer|BottomTab|MaterialTopTab)Navigator\\s*\\(\\s*\\{/;\n const v4StartMatch = v4StartRegex.exec(source);\n if (v4StartMatch && screens.length === 0) {\n const startIdx = v4StartMatch.index + v4StartMatch[0].length;\n // Use brace-counting to find the matching closing brace\n let depth = 1;\n let i = startIdx;\n while (i < source.length && depth > 0) {\n if (source[i] === '{') depth++;\n else if (source[i] === '}') depth--;\n i++;\n }\n const body = source.substring(startIdx, i - 1);\n\n // Match: Home: { screen: HomeScreen } or Home: HomeScreen\n const screenRegex = /(\\w+)\\s*:\\s*(?:\\{\\s*screen\\s*:\\s*(\\w+)|(\\w+))/g;\n let sm: RegExpExecArray | null;\n while ((sm = screenRegex.exec(body)) !== null) {\n const screenName = sm[1];\n const component = sm[2] ?? sm[3];\n // Skip navigator option keys and sub-object keys\n if (['initialRouteName', 'navigationOptions', 'defaultNavigationOptions', 'mode', 'headerMode', 'screen'].includes(screenName)) continue;\n screens.push({\n name: screenName,\n componentPath: component,\n navigatorType: navigatorType ?? 'stack',\n });\n }\n }\n\n // Extract deep linking config\n const deepLinks = extractDeepLinkConfig(source);\n for (const screen of screens) {\n const link = deepLinks.get(screen.name);\n if (link) {\n screen.deepLink = link;\n }\n }\n\n return screens;\n}\n\n/**\n * Detect the navigator type from creation calls.\n */\nfunction detectNavigatorType(source: string): RawRnScreen['navigatorType'] | undefined {\n if (/createNativeStackNavigator|createStackNavigator/.test(source)) return 'native-stack';\n if (/createBottomTabNavigator|createMaterialTopTabNavigator|createTabNavigator/.test(source)) return 'tab';\n if (/createDrawerNavigator/.test(source)) return 'drawer';\n return undefined;\n}\n\n/**\n * Extract navigation.navigate() calls → which screens are navigated to.\n */\nexport function extractNavigationCalls(source: string): string[] {\n const targets: string[] = [];\n const regex = /navigation\\.(navigate|push|reset)\\s*\\(\\s*['\"](\\w+)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(source)) !== null) {\n targets.push(match[2]);\n }\n return [...new Set(targets)];\n}\n\n/**\n * Extract Expo Router navigation calls:\n * - router.push('/path'), router.replace('/path'), router.navigate('/path')\n * - <Link href=\"/path\" />\n * - router.push({ pathname: '/path' })\n *\n * Returns raw path strings (e.g. '/settings', '/profile/123').\n */\nexport function extractExpoNavigationCalls(source: string): string[] {\n const paths: string[] = [];\n\n // router.push('/path'), router.replace('/path'), router.navigate('/path')\n const routerCallRegex = /router\\.(push|replace|navigate)\\s*\\(\\s*['\"]([^'\"]+)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = routerCallRegex.exec(source)) !== null) {\n paths.push(match[2]);\n }\n\n // router.push(`/path/${id}`) — template literal with simple interpolation\n const templateRegex = /router\\.(push|replace|navigate)\\s*\\(\\s*`([^`]+)`/g;\n while ((match = templateRegex.exec(source)) !== null) {\n // Replace ${...} with :param placeholder for route matching\n const path = match[2].replace(/\\$\\{[^}]+\\}/g, ':param');\n paths.push(path);\n }\n\n // <Link href=\"/path\" /> or <Link href={\"/path\"} />\n const linkRegex = /<Link\\s+[^>]*href\\s*=\\s*(?:\\{?\\s*)?['\"]([^'\"]+)['\"]/g;\n while ((match = linkRegex.exec(source)) !== null) {\n paths.push(match[1]);\n }\n\n // router.push({ pathname: '/path' })\n const objectRegex = /router\\.(push|replace|navigate)\\s*\\(\\s*\\{[^}]*pathname\\s*:\\s*['\"]([^'\"]+)['\"]/g;\n while ((match = objectRegex.exec(source)) !== null) {\n paths.push(match[2]);\n }\n\n return [...new Set(paths)];\n}\n\n/**\n * Match a concrete URL path (e.g. '/profile/123') against an Expo Router\n * route pattern (e.g. '/profile/:id'). Returns true if they match.\n */\nexport function matchExpoRoute(path: string, routePattern: string): boolean {\n if (path === routePattern) return true;\n\n const pathParts = path.split('/').filter(Boolean);\n const routeParts = routePattern.split('/').filter(Boolean);\n\n if (pathParts.length !== routeParts.length) {\n // Check for catch-all (*) at end\n if (routeParts[routeParts.length - 1] === '*' && pathParts.length >= routeParts.length - 1) {\n return routeParts.slice(0, -1).every((rp, i) => rp.startsWith(':') || rp === pathParts[i]);\n }\n return false;\n }\n\n return routeParts.every((rp, i) =>\n rp.startsWith(':') || rp === ':param' || rp === pathParts[i],\n );\n}\n\n/**\n * Extract deep linking configuration.\n */\nfunction extractDeepLinkConfig(source: string): Map<string, string> {\n const links = new Map<string, string>();\n\n // Match: config: { screens: { Home: '', Profile: 'user/:id' } }\n const configRegex = /screens\\s*:\\s*\\{([\\s\\S]*?)\\}/;\n const configMatch = source.match(configRegex);\n if (!configMatch) return links;\n\n const screenRegex = /(\\w+)\\s*:\\s*['\"]([^'\"]*)['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = screenRegex.exec(configMatch[1])) !== null) {\n links.set(match[1], match[2]);\n }\n\n return links;\n}\n\n/**\n * Detect platform-specific file from path.\n */\nexport function isPlatformSpecificFile(filePath: string): boolean {\n return /\\.(ios|android|native|web)\\.(tsx?|jsx?)$/.test(filePath);\n}\n\n/**\n * Extract platform from file path.\n */\nexport function getPlatform(filePath: string): string | null {\n const match = filePath.match(/\\.(ios|android|native|web)\\.(tsx?|jsx?)$/);\n return match ? match[1] : null;\n}\n\n/**\n * Detect NativeModules or TurboModuleRegistry usage.\n */\nexport function hasNativeModuleUsage(source: string): boolean {\n return /\\bNativeModules\\b/.test(source)\n || /\\bTurboModuleRegistry\\b/.test(source)\n || /\\brequireNativeComponent\\b/.test(source);\n}\n\n/**\n * Extract native module names from usage.\n */\nexport function extractNativeModuleNames(source: string): string[] {\n const modules: string[] = [];\n\n // NativeModules.ModuleName or const { ModuleName } = NativeModules\n const destructRegex = /(?:const|let|var)\\s*\\{([^}]+)\\}\\s*=\\s*NativeModules/g;\n let match: RegExpExecArray | null;\n while ((match = destructRegex.exec(source)) !== null) {\n const names = match[1].split(',').map((n) => n.trim()).filter(Boolean);\n modules.push(...names);\n }\n\n const dotRegex = /NativeModules\\.(\\w+)/g;\n while ((match = dotRegex.exec(source)) !== null) {\n modules.push(match[1]);\n }\n\n // TurboModuleRegistry.getEnforcing<Spec>('ModuleName')\n const turboRegex = /TurboModuleRegistry\\.(?:getEnforcing|get)\\s*(?:<[^>]*>)?\\s*\\(\\s*['\"](\\w+)['\"]\\s*\\)/g;\n while ((match = turboRegex.exec(source)) !== null) {\n modules.push(match[1]);\n }\n\n // requireNativeComponent('ViewName')\n const nativeCompRegex = /requireNativeComponent\\s*\\(\\s*['\"](\\w+)['\"]\\s*\\)/g;\n while ((match = nativeCompRegex.exec(source)) !== null) {\n modules.push(match[1]);\n }\n\n return [...new Set(modules)];\n}\n","/**\n * PrismaPlugin — parses Prisma schema files (schema.prisma / *.prisma).\n *\n * Implements BOTH LanguagePlugin (so .prisma files are not skipped by the pipeline)\n * and FrameworkPlugin (for richer ORM model/association extraction).\n *\n * Extracts:\n * - model blocks → RawOrmModel with fields, relations, @@map table names\n * - enum blocks → stored as ORM model with orm='prisma_enum'\n * - @relation fields → RawOrmAssociation\n * - @@index / @@unique → stored in model metadata\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n LanguagePlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawOrmModel,\n RawOrmAssociation,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\n\n// ── LanguagePlugin half ────────────────────────────────────────────────────\n\nexport class PrismaLanguagePlugin implements LanguagePlugin {\n manifest: PluginManifest = {\n name: 'prisma-language',\n version: '1.0.0',\n priority: 5,\n dependencies: [],\n };\n\n supportedExtensions = ['.prisma'];\n\n extractSymbols(filePath: string, content: Buffer): TraceMcpResult<FileParseResult> {\n // Let the framework plugin do the heavy work; here we just mark the file\n // as language='prisma' with no symbols so the pipeline doesn't skip it.\n return ok({\n status: 'ok',\n symbols: [],\n language: 'prisma',\n });\n }\n}\n\n// ── FrameworkPlugin half ───────────────────────────────────────────────────\n\nexport class PrismaPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'prisma',\n version: '1.0.0',\n priority: 30,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n // Check package.json for @prisma/client\n const deps = {\n ...(ctx.packageJson?.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson?.devDependencies as Record<string, string> | undefined),\n };\n if ('@prisma/client' in deps || 'prisma' in deps) return true;\n\n // Also detect if any schema.prisma exists under the project root\n try {\n const candidates = [\n path.join(ctx.rootPath, 'prisma', 'schema.prisma'),\n path.join(ctx.rootPath, 'schema.prisma'),\n ];\n return candidates.some((p) => fs.existsSync(p));\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'prisma_relation', category: 'prisma', description: 'Prisma model relation' },\n { name: 'prisma_implicit_m2m', category: 'prisma', description: 'Prisma implicit many-to-many' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'prisma') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const { models, associations } = parsePrismaSchema(source);\n\n return ok({\n status: 'ok',\n symbols: [],\n ormModels: models,\n ormAssociations: associations,\n frameworkRole: 'prisma_schema',\n });\n }\n\n resolveEdges(_ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n\n// ── Parser ─────────────────────────────────────────────────────────────────\n\ninterface ParseResult {\n models: RawOrmModel[];\n associations: RawOrmAssociation[];\n}\n\nexport function parsePrismaSchema(source: string): ParseResult {\n const models: RawOrmModel[] = [];\n const associations: RawOrmAssociation[] = [];\n\n // Strip line comments\n const stripped = source.replace(/\\/\\/[^\\n]*/g, '');\n\n // Extract all top-level blocks: model, enum, type\n const blockRegex = /\\b(model|enum|type)\\s+(\\w+)\\s*\\{([^}]*)\\}/g;\n let blockMatch: RegExpExecArray | null;\n\n while ((blockMatch = blockRegex.exec(stripped)) !== null) {\n const blockKind = blockMatch[1];\n const blockName = blockMatch[2];\n const blockBody = blockMatch[3];\n\n if (blockKind === 'enum') {\n // Store enum as a special ORM model\n const values = blockBody\n .split('\\n')\n .map((l) => l.trim())\n .filter((l) => l && !l.startsWith('@@'));\n models.push({\n name: blockName,\n orm: 'prisma',\n metadata: { kind: 'enum', values },\n });\n continue;\n }\n\n // model or type block\n const fields: Record<string, unknown>[] = [];\n const indices: string[] = [];\n let tableName: string | undefined;\n\n for (const rawLine of blockBody.split('\\n')) {\n const line = rawLine.trim();\n if (!line) continue;\n\n // Block-level attributes\n if (line.startsWith('@@map(')) {\n const m = line.match(/@@map\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/);\n if (m) tableName = m[1];\n continue;\n }\n if (line.startsWith('@@index') || line.startsWith('@@unique') || line.startsWith('@@id')) {\n indices.push(line);\n continue;\n }\n if (line.startsWith('@@')) continue;\n\n // Field line: fieldName FieldType @attr @attr2\n const fieldMatch = line.match(/^(\\w+)\\s+([\\w?[\\]]+)(.*)?$/);\n if (!fieldMatch) continue;\n\n const fieldName = fieldMatch[1];\n const fieldType = fieldMatch[2];\n const attrs = fieldMatch[3] ?? '';\n\n // Skip native-type fields that are just Prisma internals\n if (['@@', '//'].some((p) => fieldName.startsWith(p))) continue;\n\n const field: Record<string, unknown> = {\n name: fieldName,\n type: fieldType.replace('?', '').replace('[]', ''),\n optional: fieldType.includes('?'),\n list: fieldType.includes('[]'),\n };\n\n if (/@id\\b/.test(attrs)) field.id = true;\n if (/@unique\\b/.test(attrs)) field.unique = true;\n if (/@default/.test(attrs)) {\n const dm = attrs.match(/@default\\(([^)]+)\\)/);\n if (dm) field.default = dm[1];\n }\n if (/@updatedAt\\b/.test(attrs)) field.updatedAt = true;\n\n // @map(\"column_name\")\n const mapMatch = attrs.match(/@map\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/);\n if (mapMatch) field.columnName = mapMatch[1];\n\n // @relation — collect for associations\n if (/@relation\\b/.test(attrs)) {\n const relNameMatch = attrs.match(/@relation\\s*\\(\\s*(?:name\\s*:\\s*)?[\"']([^\"']+)[\"']/);\n const fieldsMatch = attrs.match(/fields\\s*:\\s*\\[([^\\]]+)\\]/);\n const referencesMatch = attrs.match(/references\\s*:\\s*\\[([^\\]]+)\\]/);\n\n // Target type (strip ? and [])\n const targetType = fieldType.replace('?', '').replace('[]', '');\n\n // Only add one direction of the relation (the side that has `fields:`)\n if (fieldsMatch) {\n associations.push({\n sourceModelName: blockName,\n targetModelName: targetType,\n kind: fieldType.includes('[]') ? 'hasMany' : 'belongsTo',\n options: {\n ...(relNameMatch ? { name: relNameMatch[1] } : {}),\n fields: fieldsMatch[1].split(',').map((s) => s.trim()),\n references: referencesMatch\n ? referencesMatch[1].split(',').map((s) => s.trim())\n : [],\n },\n });\n }\n\n field.relation = true;\n field.relationType = fieldType.includes('[]') ? 'hasMany' : 'belongsTo';\n field.relationTarget = targetType;\n }\n\n fields.push(field);\n }\n\n models.push({\n name: blockName,\n orm: 'prisma',\n collectionOrTable: tableName,\n fields,\n metadata: {\n kind: blockKind,\n indices: indices.length > 0 ? indices : undefined,\n },\n });\n }\n\n return { models, associations };\n}\n","/**\n * GraphQLPlugin — indexes GraphQL schemas and resolvers.\n *\n * Language plugin: handles .graphql / .gql files.\n * Framework plugin: extracts resolver wiring from TypeScript resolver files.\n *\n * Extracts:\n * - SDL type/input/interface/union/enum definitions → symbols (kind='type')\n * - SDL fields with arguments → symbols (kind='method')\n * - Resolver objects (const resolvers = { Query: { ... } }) → edges (graphql_resolves)\n * - TypeDefs string literals inside .ts files (gql`...` template literals)\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n LanguagePlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawSymbol,\n RawEdge,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\n\n// ── Language plugin: .graphql / .gql files ────────────────────────────────\n\nexport class GraphQLLanguagePlugin implements LanguagePlugin {\n manifest: PluginManifest = {\n name: 'graphql-language',\n version: '1.0.0',\n priority: 5,\n dependencies: [],\n };\n\n supportedExtensions = ['.graphql', '.gql'];\n\n extractSymbols(filePath: string, content: Buffer): TraceMcpResult<FileParseResult> {\n const source = content.toString('utf-8');\n const symbols = extractSchemaSymbols(source, filePath);\n return ok({ status: 'ok', symbols, language: 'graphql' });\n }\n}\n\n// ── Framework plugin: wires resolvers in TypeScript/JS files ─────────────\n\nexport class GraphQLPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'graphql',\n version: '1.0.0',\n priority: 40,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n const deps = {\n ...(ctx.packageJson?.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson?.devDependencies as Record<string, string> | undefined),\n };\n const gqlDeps = ['graphql', 'apollo-server', '@apollo/server', 'type-graphql',\n 'nexus', 'pothos', '@pothos/core', 'mercurius', 'graphql-yoga'];\n if (gqlDeps.some((d) => d in deps)) return true;\n\n // Also check for any .graphql file in the project root\n try {\n return fs.readdirSync(ctx.rootPath).some((f) => f.endsWith('.graphql') || f.endsWith('.gql'));\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'graphql_resolves', category: 'graphql', description: 'Resolver function implements a GraphQL field' },\n { name: 'graphql_references_type', category: 'graphql', description: 'Field/resolver references a GraphQL type' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'typescript' && language !== 'javascript') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n\n // Extract embedded SDL from gql`` template literals and typeDefs strings\n const sdlSymbols = extractEmbeddedSdl(source, filePath);\n\n // Extract resolver object patterns and produce metadata symbols\n const resolverInfo = extractResolverObjects(source, filePath);\n\n return ok({\n status: 'ok',\n symbols: [...sdlSymbols, ...resolverInfo.symbols],\n edges: resolverInfo.edges.length > 0 ? resolverInfo.edges : undefined,\n frameworkRole: sdlSymbols.length > 0 || resolverInfo.symbols.length > 0\n ? 'graphql_resolver'\n : undefined,\n });\n }\n\n resolveEdges(_ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n\n// ── SDL symbol extraction ──────────────────────────────────────────────────\n\nfunction extractSchemaSymbols(source: string, filePath: string): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n const lines = source.split('\\n');\n const byteOffsets = buildByteOffsets(lines);\n\n // Strip block comments\n const stripped = source.replace(/\"\"\"[\\s\\S]*?\"\"\"/g, '\"\"\" \"\"\"');\n\n const blockRegex = /\\b(type|input|interface|union|enum|scalar|directive)\\s+(\\w+)[^{]*\\{?/g;\n let match: RegExpExecArray | null;\n\n while ((match = blockRegex.exec(stripped)) !== null) {\n const keyword = match[1];\n const name = match[2];\n\n // Skip built-in types\n if (['String', 'Int', 'Float', 'Boolean', 'ID'].includes(name)) continue;\n\n const lineIdx = source.slice(0, match.index).split('\\n').length - 1;\n const byteStart = byteOffsets[lineIdx] ?? match.index;\n\n // Find closing brace for the block\n let braceDepth = 0;\n let endPos = match.index;\n for (let j = match.index; j < source.length; j++) {\n if (source[j] === '{') braceDepth++;\n else if (source[j] === '}') {\n braceDepth--;\n if (braceDepth === 0) { endPos = j + 1; break; }\n }\n }\n\n const blockContent = source.slice(match.index, endPos);\n const endLineIdx = source.slice(0, endPos).split('\\n').length - 1;\n const byteEnd = byteOffsets[endLineIdx] + (lines[endLineIdx]?.length ?? 0);\n\n symbols.push({\n symbolId: `${filePath}::${name}#type`,\n name,\n kind: 'type',\n fqn: name,\n signature: `${keyword} ${name}`,\n byteStart,\n byteEnd,\n lineStart: lineIdx + 1,\n lineEnd: endLineIdx + 1,\n });\n\n // Extract fields from type/input/interface blocks\n if ((keyword === 'type' || keyword === 'input' || keyword === 'interface') && blockContent.includes('{')) {\n const bodyMatch = blockContent.match(/\\{([\\s\\S]*)\\}/);\n if (bodyMatch) {\n const fieldRegex = /^\\s*(\\w+)\\s*(?:\\([^)]*\\))?\\s*:\\s*([\\w!\\[\\]]+)/gm;\n let fieldMatch: RegExpExecArray | null;\n while ((fieldMatch = fieldRegex.exec(bodyMatch[1])) !== null) {\n const fieldName = fieldMatch[1];\n if (['__typename', ''].includes(fieldName)) continue;\n const bodyMatchIndex = bodyMatch.index ?? 0;\n const fieldLineOffset = blockContent.slice(0, bodyMatchIndex + fieldMatch.index).split('\\n').length - 1;\n symbols.push({\n symbolId: `${filePath}::${name}::${fieldName}#method`,\n name: fieldName,\n kind: 'method',\n fqn: `${name}.${fieldName}`,\n parentSymbolId: `${filePath}::${name}#type`,\n signature: `${fieldName}: ${fieldMatch[2]}`,\n byteStart: byteStart + fieldMatch.index,\n byteEnd: byteStart + fieldMatch.index + fieldMatch[0].length,\n lineStart: lineIdx + fieldLineOffset + 1,\n lineEnd: lineIdx + fieldLineOffset + 1,\n });\n }\n }\n }\n }\n\n return symbols;\n}\n\n// ── Embedded SDL extraction ────────────────────────────────────────────────\n\nfunction extractEmbeddedSdl(source: string, filePath: string): RawSymbol[] {\n const symbols: RawSymbol[] = [];\n\n // Match gql`...` or graphql`...` template literals\n const gqlRegex = /(?:gql|graphql)\\s*`([\\s\\S]*?)`/g;\n let match: RegExpExecArray | null;\n while ((match = gqlRegex.exec(source)) !== null) {\n const sdl = match[1];\n const embedded = extractSchemaSymbols(sdl, `${filePath}@embedded`);\n symbols.push(...embedded);\n }\n\n return symbols;\n}\n\n// ── Resolver object extraction ─────────────────────────────────────────────\n\ninterface ResolverResult {\n symbols: RawSymbol[];\n edges: RawEdge[];\n}\n\nfunction extractResolverObjects(source: string, filePath: string): ResolverResult {\n const symbols: RawSymbol[] = [];\n const edges: RawEdge[] = [];\n\n // Match: const resolvers = { Query: { fieldName: ... }, Mutation: { ... }, TypeName: { ... } }\n // or: export const resolvers: Resolvers = { ... }\n const resolverVarRegex = /(?:const|export\\s+const)\\s+resolvers\\s*(?::[^=]+)?\\s*=\\s*\\{/;\n const match = resolverVarRegex.exec(source);\n if (!match) return { symbols, edges };\n\n // Extract type keys (Query, Mutation, Subscription, TypeName)\n const typeKeyRegex = /\\b(Query|Mutation|Subscription|[\\w]+)\\s*:\\s*\\{/g;\n let typeMatch: RegExpExecArray | null;\n while ((typeMatch = typeKeyRegex.exec(source.slice(match.index))) !== null) {\n const typeName = typeMatch[1];\n\n // Extract field resolvers within this type block\n // Find the opening brace position\n const typeStart = match.index + typeMatch.index + typeMatch[0].length;\n let depth = 1;\n let pos = typeStart;\n const typeBody: string[] = [];\n\n while (pos < source.length && depth > 0) {\n if (source[pos] === '{') depth++;\n else if (source[pos] === '}') depth--;\n if (depth > 0) typeBody.push(source[pos]);\n pos++;\n }\n\n // Extract resolver field names\n const fieldRegex = /\\b(\\w+)\\s*(?::\\s*(?:async\\s+)?(?:function\\s*\\w*|\\([^)]*\\)\\s*=>|\\w+\\s*=>))/g;\n let fieldMatch: RegExpExecArray | null;\n const body = typeBody.join('');\n while ((fieldMatch = fieldRegex.exec(body)) !== null) {\n const fieldName = fieldMatch[1];\n const lineIdx = source.slice(0, match.index + typeMatch.index + fieldMatch.index).split('\\n').length - 1;\n\n symbols.push({\n symbolId: `${filePath}::${typeName}::${fieldName}#function`,\n name: fieldName,\n kind: 'function',\n fqn: `${typeName}.${fieldName}`,\n signature: `${typeName}.${fieldName}(parent, args, ctx)`,\n byteStart: match.index + typeMatch.index,\n byteEnd: match.index + typeMatch.index + fieldMatch[0].length,\n lineStart: lineIdx + 1,\n lineEnd: lineIdx + 1,\n metadata: { resolverType: typeName, resolverField: fieldName },\n });\n\n // Edge: resolver → graphql type field\n edges.push({\n sourceSymbolId: `${filePath}::${typeName}::${fieldName}#function`,\n edgeType: 'graphql_resolves',\n resolved: false,\n metadata: { typeName, fieldName },\n } as RawEdge);\n }\n }\n\n return { symbols, edges };\n}\n\n// ── Utility ────────────────────────────────────────────────────────────────\n\nfunction buildByteOffsets(lines: string[]): number[] {\n const offsets: number[] = [];\n let offset = 0;\n for (const line of lines) {\n offsets.push(offset);\n offset += Buffer.byteLength(line, 'utf-8') + 1;\n }\n return offsets;\n}\n","/**\n * TypeORMPlugin — Framework plugin for TypeORM.\n *\n * Extracts:\n * - @Entity() decorated classes → RawOrmModel\n * - @Column() / @PrimaryGeneratedColumn() fields\n * - @OneToMany / @ManyToOne / @OneToOne / @ManyToMany relations → RawOrmAssociation\n * - @Index / @Unique block attributes\n *\n * Supports TypeORM 0.2.x and 0.3.x.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawOrmModel,\n RawOrmAssociation,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\n\nexport class TypeORMPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'typeorm',\n version: '1.0.0',\n priority: 30,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n const deps = {\n ...(ctx.packageJson?.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson?.devDependencies as Record<string, string> | undefined),\n };\n return 'typeorm' in deps;\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'typeorm_one_to_many', category: 'typeorm', description: 'TypeORM OneToMany' },\n { name: 'typeorm_many_to_one', category: 'typeorm', description: 'TypeORM ManyToOne' },\n { name: 'typeorm_one_to_one', category: 'typeorm', description: 'TypeORM OneToOne' },\n { name: 'typeorm_many_to_many', category: 'typeorm', description: 'TypeORM ManyToMany' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'typescript' && language !== 'javascript') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n\n // Only process files that have @Entity decorator\n if (!/@Entity\\s*\\(/.test(source)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const result = extractTypeORMEntity(source, filePath);\n if (!result) return ok({ status: 'ok', symbols: [] });\n\n return ok({\n status: 'ok',\n symbols: [],\n ormModels: [result.model],\n ormAssociations: result.associations,\n frameworkRole: 'typeorm_entity',\n });\n }\n\n resolveEdges(_ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n\n// ── Extraction ─────────────────────────────────────────────────────────────\n\ninterface TypeORMEntityResult {\n model: RawOrmModel;\n associations: RawOrmAssociation[];\n}\n\nexport function extractTypeORMEntity(\n source: string,\n filePath: string,\n): TypeORMEntityResult | null {\n // Match @Entity() ... class ClassName\n const entityRegex = /@Entity\\s*\\(\\s*(?:['\"]([^'\"]+)['\"]|\\{[^}]*tableName\\s*:\\s*['\"]([^'\"]+)['\"][^}]*\\})?\\s*\\)[\\s\\S]*?class\\s+(\\w+)/;\n const entityMatch = source.match(entityRegex);\n if (!entityMatch) return null;\n\n const tableName = entityMatch[1] || entityMatch[2];\n const className = entityMatch[3];\n\n const fields: Record<string, unknown>[] = [];\n const associations: RawOrmAssociation[] = [];\n const indices: string[] = [];\n\n // Extract @Column, @PrimaryGeneratedColumn, @PrimaryColumn fields\n const columnRegex = /@(PrimaryGeneratedColumn|PrimaryColumn|Column|CreateDateColumn|UpdateDateColumn|DeleteDateColumn)\\s*(?:\\([^)]*\\))?\\s*(?:\\w+\\s*[?!]?\\s*:\\s*[\\w|]+\\s*)*\\s*(\\w+)\\s*[?!]?\\s*:\\s*([\\w|[\\]<>]+)/g;\n let colMatch: RegExpExecArray | null;\n while ((colMatch = columnRegex.exec(source)) !== null) {\n const decorator = colMatch[1];\n const fieldName = colMatch[2];\n const fieldType = colMatch[3];\n\n const field: Record<string, unknown> = { name: fieldName, type: fieldType };\n if (decorator.startsWith('Primary')) field.primaryKey = true;\n if (decorator === 'PrimaryGeneratedColumn') field.autoIncrement = true;\n if (decorator === 'CreateDateColumn') field.createdAt = true;\n if (decorator === 'UpdateDateColumn') field.updatedAt = true;\n if (decorator === 'DeleteDateColumn') field.deletedAt = true;\n fields.push(field);\n }\n\n // Extract relation decorators\n const RELATION_MAP: Record<string, string> = {\n OneToMany: 'typeorm_one_to_many',\n ManyToOne: 'typeorm_many_to_one',\n OneToOne: 'typeorm_one_to_one',\n ManyToMany: 'typeorm_many_to_many',\n };\n\n const relationRegex = /@(OneToMany|ManyToOne|OneToOne|ManyToMany)\\s*\\(\\s*\\(\\)\\s*=>\\s*(\\w+)/g;\n let relMatch: RegExpExecArray | null;\n while ((relMatch = relationRegex.exec(source)) !== null) {\n const relKind = relMatch[1];\n const targetType = relMatch[2];\n associations.push({\n sourceModelName: className,\n targetModelName: targetType,\n kind: relKind,\n });\n }\n\n // Extract @Index block decorators\n const indexRegex = /@Index\\s*\\(\\s*\\[([^\\]]+)\\]/g;\n let idxMatch: RegExpExecArray | null;\n while ((idxMatch = indexRegex.exec(source)) !== null) {\n indices.push(idxMatch[1]);\n }\n\n const model: RawOrmModel = {\n name: className,\n orm: 'typeorm',\n collectionOrTable: tableName,\n fields,\n metadata: {\n indices: indices.length > 0 ? indices : undefined,\n },\n };\n\n return { model, associations };\n}\n","/**\n * DrizzlePlugin — Framework plugin for Drizzle ORM.\n *\n * Extracts:\n * - pgTable / mysqlTable / sqliteTable calls → RawOrmModel with fields\n * - relations() blocks → RawOrmAssociation\n * - Column types (integer, text, varchar, boolean, timestamp, json, etc.)\n *\n * Supports drizzle-orm 0.27+.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawOrmModel,\n RawOrmAssociation,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\n\nexport class DrizzlePlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'drizzle',\n version: '1.0.0',\n priority: 30,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n const deps = {\n ...(ctx.packageJson?.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson?.devDependencies as Record<string, string> | undefined),\n };\n return 'drizzle-orm' in deps;\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'drizzle_relation', category: 'drizzle', description: 'Drizzle ORM relation' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'typescript' && language !== 'javascript') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n\n // Only process files that use drizzle table definitions\n if (!/(?:pgTable|mysqlTable|sqliteTable|mySqlTable)\\s*\\(/.test(source)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const models: RawOrmModel[] = [];\n const associations: RawOrmAssociation[] = [];\n\n // Extract table definitions:\n // export const users = pgTable('users', { ... })\n // export const usersTable = pgTable('users', { ... }, (table) => ({ ... }))\n // Use two-step approach: regex to find the declaration header, then brace-matching for body\n const tableHeaderRegex = /(?:export\\s+)?(?:const|let)\\s+(\\w+)\\s*=\\s*(?:pgTable|mysqlTable|mySqlTable|sqliteTable)\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*,\\s*/g;\n let tableMatch: RegExpExecArray | null;\n while ((tableMatch = tableHeaderRegex.exec(source)) !== null) {\n const varName = tableMatch[1];\n const tableName = tableMatch[2];\n const bodyStart = tableMatch.index + tableMatch[0].length;\n const columnsBody = extractBracedBody(source, bodyStart);\n\n const fields = parseDrizzleColumns(columnsBody);\n const modelName = toModelName(varName);\n\n models.push({\n name: modelName,\n orm: 'drizzle',\n collectionOrTable: tableName,\n fields,\n metadata: { varName },\n });\n }\n\n // Extract relations() calls:\n // export const usersRelations = relations(users, ({ one, many }) => ({ posts: many(posts) }))\n const relationsRegex = /(?:export\\s+)?(?:const|let)\\s+(\\w+Relations)\\s*=\\s*relations\\s*\\(\\s*(\\w+)\\s*,/g;\n let relMatch: RegExpExecArray | null;\n while ((relMatch = relationsRegex.exec(source)) !== null) {\n const sourceVar = relMatch[2];\n const sourceModel = toModelName(sourceVar);\n\n // Find the arrow function body: relations(table, (helpers) => ({ ... }))\n // Skip past '=>' to reach the return value object, not the argument list.\n const startPos = relMatch.index + relMatch[0].length;\n const arrowPos = source.indexOf('=>', startPos);\n if (arrowPos === -1) continue;\n const relBody = extractBracedBody(source, arrowPos + 2);\n\n // one(targetTable) or many(targetTable)\n const oneRegex = /\\bone\\s*\\(\\s*(\\w+)/g;\n const manyRegex = /\\bmany\\s*\\(\\s*(\\w+)/g;\n\n let oneMatch: RegExpExecArray | null;\n while ((oneMatch = oneRegex.exec(relBody)) !== null) {\n associations.push({\n sourceModelName: sourceModel,\n targetModelName: toModelName(oneMatch[1]),\n kind: 'belongsTo',\n });\n }\n\n let manyMatch: RegExpExecArray | null;\n while ((manyMatch = manyRegex.exec(relBody)) !== null) {\n associations.push({\n sourceModelName: sourceModel,\n targetModelName: toModelName(manyMatch[1]),\n kind: 'hasMany',\n });\n }\n }\n\n if (models.length === 0) return ok({ status: 'ok', symbols: [] });\n\n return ok({\n status: 'ok',\n symbols: [],\n ormModels: models,\n ormAssociations: associations,\n frameworkRole: 'drizzle_schema',\n });\n }\n\n resolveEdges(_ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────\n\nfunction parseDrizzleColumns(body: string): Record<string, unknown>[] {\n const fields: Record<string, unknown>[] = [];\n\n // fieldName: integer('col_name').primaryKey().notNull()\n // Also handles: varchar('col', { length: 255 }).unique()\n // Also handles: .references(() => users.id) with nested parens\n const fieldRegex = /(\\w+)\\s*:\\s*(\\w+)\\s*\\([^)]*\\)([^\\n,]*)/g;\n let match: RegExpExecArray | null;\n while ((match = fieldRegex.exec(body)) !== null) {\n const name = match[1];\n const colType = match[2];\n const chain = match[3] ?? '';\n\n if (['one', 'many', 'relations'].includes(name)) continue;\n\n const field: Record<string, unknown> = { name, type: colType };\n if (/\\.primaryKey\\(/.test(chain)) field.primaryKey = true;\n if (/\\.notNull\\(/.test(chain)) field.notNull = true;\n if (/\\.unique\\(/.test(chain)) field.unique = true;\n if (/\\.default\\(/.test(chain)) {\n const dm = chain.match(/\\.default\\(([^)]+)\\)/);\n if (dm) field.default = dm[1];\n }\n if (/\\.references\\(/.test(chain)) {\n const rm = chain.match(/\\.references\\s*\\(\\s*\\(\\)\\s*=>\\s*(\\w+)\\s*\\.\\s*(\\w+)/);\n if (rm) field.references = `${rm[1]}.${rm[2]}`;\n }\n fields.push(field);\n }\n\n return fields;\n}\n\n/** Find the content inside the next {...} or (...) block after pos */\nfunction extractBracedBody(source: string, pos: number): string {\n // Skip to opening brace/paren\n let start = pos;\n while (start < source.length && source[start] !== '{' && source[start] !== '(') start++;\n if (start >= source.length) return '';\n\n const open = source[start];\n const close = open === '{' ? '}' : ')';\n let depth = 1;\n let i = start + 1;\n while (i < source.length && depth > 0) {\n if (source[i] === open) depth++;\n else if (source[i] === close) depth--;\n i++;\n }\n return source.slice(start + 1, i - 1);\n}\n\n/** Convert varName like 'usersTable' or 'users' → 'User' / 'Users' */\nfunction toModelName(varName: string): string {\n const stripped = varName.replace(/Table$/, '').replace(/s$/, '');\n return stripped.charAt(0).toUpperCase() + stripped.slice(1);\n}\n","/**\n * DRFPlugin — Django REST Framework plugin.\n *\n * Detects 'djangorestframework' in Python dependencies and extracts:\n * - ModelSerializer → Django Model edges (drf_serializer_model)\n * - ViewSet → Serializer edges (drf_viewset_serializer)\n * - router.register() → ViewSet edges + REST route generation (drf_router_registers)\n * - ViewSet → Permission class edges (drf_permission_guards)\n *\n * Uses tree-sitter-python for AST-based extraction.\n */\nimport { createRequire } from 'node:module';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, err } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n ResolveContext,\n EdgeTypeDeclaration,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\nimport { parseError } from '../../../../errors.js';\nimport { escapeRegExp } from '../../../../utils/security.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst PythonGrammar = require('tree-sitter-python');\n\n// tree-sitter types (CJS interop)\ntype TSNode = {\n type: string;\n text: string;\n startIndex: number;\n endIndex: number;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n namedChildCount: number;\n childCount: number;\n namedChildren: TSNode[];\n namedChild(index: number): TSNode | null;\n child(index: number): TSNode | null;\n childForFieldName(name: string): TSNode | null;\n parent: TSNode | null;\n isNamed: boolean;\n hasError: boolean;\n};\n\nlet parserInstance: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(): InstanceType<typeof Parser> {\n if (!parserInstance) {\n parserInstance = new Parser();\n parserInstance!.setLanguage(PythonGrammar);\n }\n return parserInstance!;\n}\n\n// ============================================================\n// Python dependency detection\n// ============================================================\n\nfunction hasPythonDep(rootPath: string, depName: string): boolean {\n // Check requirements.txt\n for (const reqFile of ['requirements.txt', 'requirements/base.txt', 'requirements/prod.txt']) {\n try {\n const content = fs.readFileSync(path.join(rootPath, reqFile), 'utf-8');\n if (new RegExp(`^${escapeRegExp(depName)}\\\\b`, 'm').test(content)) return true;\n } catch { /* not found */ }\n }\n\n // Check pyproject.toml\n try {\n const content = fs.readFileSync(path.join(rootPath, 'pyproject.toml'), 'utf-8');\n if (content.includes(depName)) return true;\n } catch { /* not found */ }\n\n // Check setup.py / setup.cfg\n for (const f of ['setup.py', 'setup.cfg']) {\n try {\n const content = fs.readFileSync(path.join(rootPath, f), 'utf-8');\n if (content.includes(depName)) return true;\n } catch { /* not found */ }\n }\n\n // Check Pipfile\n try {\n const content = fs.readFileSync(path.join(rootPath, 'Pipfile'), 'utf-8');\n if (content.includes(depName)) return true;\n } catch { /* not found */ }\n\n return false;\n}\n\n// ============================================================\n// AST helpers\n// ============================================================\n\n/** Find all top-level class definitions (including decorated ones). */\nfunction findClassDefinitions(root: TSNode): TSNode[] {\n const classes: TSNode[] = [];\n for (const child of root.namedChildren) {\n if (child.type === 'class_definition') {\n classes.push(child);\n } else if (child.type === 'decorated_definition') {\n const inner = child.namedChildren.find(c => c.type === 'class_definition');\n if (inner) classes.push(inner);\n }\n }\n return classes;\n}\n\n/** Get superclass names from a class_definition node. */\nfunction getSuperclasses(classDef: TSNode): string[] {\n const argList = classDef.childForFieldName('superclasses');\n if (!argList) return [];\n const names: string[] = [];\n for (const child of argList.namedChildren) {\n if (child.type === 'identifier') {\n names.push(child.text);\n } else if (child.type === 'attribute') {\n // e.g. serializers.ModelSerializer\n names.push(child.text);\n }\n }\n return names;\n}\n\n/** Get the class name from a class_definition node. */\nfunction getClassName(classDef: TSNode): string {\n const nameNode = classDef.childForFieldName('name');\n return nameNode?.text ?? '';\n}\n\n/** Get the body node of a class. */\nfunction getClassBody(classDef: TSNode): TSNode | null {\n return classDef.childForFieldName('body');\n}\n\n/** Find an assignment in a block by target name. Returns the RHS node. */\nfunction findAssignment(body: TSNode, targetName: string): TSNode | null {\n for (const child of body.namedChildren) {\n if (child.type === 'expression_statement') {\n const expr = child.namedChildren[0];\n if (expr?.type === 'assignment') {\n const left = expr.childForFieldName('left');\n if (left?.type === 'identifier' && left.text === targetName) {\n return expr.childForFieldName('right');\n }\n }\n }\n }\n return null;\n}\n\n/** Find a nested class (like Meta) inside a class body. */\nfunction findNestedClass(body: TSNode, name: string): TSNode | null {\n for (const child of body.namedChildren) {\n if (child.type === 'class_definition') {\n const n = child.childForFieldName('name');\n if (n?.text === name) return child;\n }\n }\n return null;\n}\n\n/** Extract list literal items as strings. Handles [Foo, Bar, ...] */\nfunction extractListItems(node: TSNode): string[] {\n if (node.type === 'list') {\n return node.namedChildren\n .filter(c => c.type === 'identifier' || c.type === 'attribute')\n .map(c => c.text);\n }\n // Might be a tuple: (Foo, Bar)\n if (node.type === 'tuple') {\n return node.namedChildren\n .filter(c => c.type === 'identifier' || c.type === 'attribute')\n .map(c => c.text);\n }\n // Single identifier\n if (node.type === 'identifier') return [node.text];\n return [];\n}\n\n/** Strip the last dotted segment to get the short name. */\nfunction shortName(name: string): string {\n const dot = name.lastIndexOf('.');\n return dot >= 0 ? name.slice(dot + 1) : name;\n}\n\n// ============================================================\n// DRF Serializer extraction\n// ============================================================\n\ninterface SerializerInfo {\n className: string;\n modelName: string | null;\n line: number;\n}\n\nconst SERIALIZER_BASES = new Set([\n 'ModelSerializer', 'serializers.ModelSerializer',\n 'HyperlinkedModelSerializer', 'serializers.HyperlinkedModelSerializer',\n]);\n\nfunction extractSerializers(root: TSNode): SerializerInfo[] {\n const result: SerializerInfo[] = [];\n for (const classDef of findClassDefinitions(root)) {\n const supers = getSuperclasses(classDef);\n const isModelSerializer = supers.some(s => SERIALIZER_BASES.has(s));\n if (!isModelSerializer) continue;\n\n const className = getClassName(classDef);\n const body = getClassBody(classDef);\n if (!body) continue;\n\n let modelName: string | null = null;\n const metaClass = findNestedClass(body, 'Meta');\n if (metaClass) {\n const metaBody = getClassBody(metaClass);\n if (metaBody) {\n const modelRhs = findAssignment(metaBody, 'model');\n if (modelRhs) {\n modelName = shortName(modelRhs.text);\n }\n }\n }\n\n result.push({\n className,\n modelName,\n line: classDef.startPosition.row + 1,\n });\n }\n return result;\n}\n\n// ============================================================\n// DRF ViewSet extraction\n// ============================================================\n\ninterface ViewSetInfo {\n className: string;\n serializerClass: string | null;\n permissionClasses: string[];\n line: number;\n}\n\nconst VIEWSET_BASES = new Set([\n 'ModelViewSet', 'viewsets.ModelViewSet',\n 'ReadOnlyModelViewSet', 'viewsets.ReadOnlyModelViewSet',\n 'ViewSet', 'viewsets.ViewSet',\n 'GenericViewSet', 'viewsets.GenericViewSet',\n 'APIView', 'GenericAPIView',\n 'ListAPIView', 'CreateAPIView', 'RetrieveAPIView',\n 'UpdateAPIView', 'DestroyAPIView',\n 'ListCreateAPIView', 'RetrieveUpdateAPIView',\n 'RetrieveDestroyAPIView', 'RetrieveUpdateDestroyAPIView',\n]);\n\nfunction extractViewSets(root: TSNode): ViewSetInfo[] {\n const result: ViewSetInfo[] = [];\n for (const classDef of findClassDefinitions(root)) {\n const supers = getSuperclasses(classDef);\n const isViewSet = supers.some(s => VIEWSET_BASES.has(s));\n if (!isViewSet) continue;\n\n const className = getClassName(classDef);\n const body = getClassBody(classDef);\n if (!body) continue;\n\n // serializer_class = UserSerializer\n let serializerClass: string | null = null;\n const serRhs = findAssignment(body, 'serializer_class');\n if (serRhs) {\n serializerClass = shortName(serRhs.text);\n }\n\n // permission_classes = [IsAuthenticated, IsAdminUser]\n let permissionClasses: string[] = [];\n const permRhs = findAssignment(body, 'permission_classes');\n if (permRhs) {\n permissionClasses = extractListItems(permRhs).map(shortName);\n }\n\n result.push({\n className,\n serializerClass,\n permissionClasses,\n line: classDef.startPosition.row + 1,\n });\n }\n return result;\n}\n\n// ============================================================\n// DRF Router extraction\n// ============================================================\n\ninterface RouterRegistration {\n prefix: string;\n viewsetName: string;\n line: number;\n}\n\n/**\n * Find router.register('prefix', ViewSet) calls.\n * Walks all call expressions in the AST.\n */\nfunction extractRouterRegistrations(root: TSNode): RouterRegistration[] {\n const result: RouterRegistration[] = [];\n walkCalls(root, (callNode) => {\n const fn = callNode.childForFieldName('function');\n if (!fn || fn.type !== 'attribute') return;\n if (fn.childForFieldName('attribute')?.text !== 'register') return;\n\n const args = callNode.childForFieldName('arguments');\n if (!args) return;\n\n const positional = args.namedChildren.filter(\n c => c.type !== 'keyword_argument' && c.type !== 'comment',\n );\n if (positional.length < 2) return;\n\n const prefixNode = positional[0];\n const viewsetNode = positional[1];\n\n // prefix should be a string literal\n let prefix = '';\n if (prefixNode.type === 'string') {\n prefix = stripQuotes(prefixNode.text);\n } else {\n return; // skip non-literal\n }\n\n const viewsetName = shortName(viewsetNode.text);\n\n result.push({\n prefix,\n viewsetName,\n line: callNode.startPosition.row + 1,\n });\n });\n return result;\n}\n\n/** Walk all call nodes in the tree. */\nfunction walkCalls(node: TSNode, visitor: (call: TSNode) => void): void {\n if (node.type === 'call') {\n visitor(node);\n }\n for (const child of node.namedChildren) {\n walkCalls(child, visitor);\n }\n}\n\nfunction stripQuotes(s: string): string {\n // Handle f-strings, byte strings, etc.\n const raw = s.replace(/^[brufBRUF]*['\"]/, '').replace(/['\"]$/, '');\n return raw;\n}\n\n// ============================================================\n// Standard CRUD routes for a DRF ViewSet\n// ============================================================\n\nfunction generateViewSetRoutes(prefix: string): RawRoute[] {\n const base = prefix.startsWith('/') ? prefix : `/${prefix}`;\n const trailing = base.endsWith('/') ? '' : '/';\n return [\n { method: 'GET', uri: `${base}${trailing}`, name: `${prefix}-list` },\n { method: 'POST', uri: `${base}${trailing}`, name: `${prefix}-create` },\n { method: 'GET', uri: `${base}${trailing}{pk}/`, name: `${prefix}-retrieve` },\n { method: 'PUT', uri: `${base}${trailing}{pk}/`, name: `${prefix}-update` },\n { method: 'PATCH', uri: `${base}${trailing}{pk}/`, name: `${prefix}-partial_update` },\n { method: 'DELETE', uri: `${base}${trailing}{pk}/`, name: `${prefix}-destroy` },\n ];\n}\n\n// ============================================================\n// Plugin class\n// ============================================================\n\nexport class DRFPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'drf',\n version: '1.0.0',\n priority: 30,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n return hasPythonDep(ctx.rootPath, 'djangorestframework');\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'drf_serializer_model', category: 'drf', description: 'ModelSerializer → Django Model' } as EdgeTypeDeclaration,\n { name: 'drf_viewset_serializer', category: 'drf', description: 'ViewSet → Serializer' } as EdgeTypeDeclaration,\n { name: 'drf_router_registers', category: 'drf', description: 'router.register() → ViewSet' } as EdgeTypeDeclaration,\n { name: 'drf_permission_guards', category: 'drf', description: 'ViewSet → Permission class' } as EdgeTypeDeclaration,\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'python') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n edges: [],\n routes: [],\n };\n\n let tree: { rootNode: TSNode };\n try {\n const parser = getParser();\n tree = parser.parse(source);\n } catch (e) {\n return err(parseError(filePath, `tree-sitter parse failed: ${e}`));\n }\n\n const root = tree.rootNode;\n\n // --- Serializers ---\n const serializers = extractSerializers(root);\n for (const ser of serializers) {\n if (ser.modelName) {\n result.edges!.push({\n edgeType: 'drf_serializer_model',\n sourceSymbolId: `${filePath}::${ser.className}#class`,\n targetSymbolId: ser.modelName, // resolved in pass 2\n metadata: { line: ser.line },\n });\n }\n result.frameworkRole = 'drf_serializer';\n }\n\n // --- ViewSets ---\n const viewsets = extractViewSets(root);\n for (const vs of viewsets) {\n if (vs.serializerClass) {\n result.edges!.push({\n edgeType: 'drf_viewset_serializer',\n sourceSymbolId: `${filePath}::${vs.className}#class`,\n targetSymbolId: vs.serializerClass, // resolved in pass 2\n metadata: { line: vs.line },\n });\n }\n\n for (const perm of vs.permissionClasses) {\n result.edges!.push({\n edgeType: 'drf_permission_guards',\n sourceSymbolId: `${filePath}::${vs.className}#class`,\n targetSymbolId: perm, // resolved in pass 2\n metadata: { line: vs.line },\n });\n }\n\n if (vs.serializerClass || vs.permissionClasses.length > 0) {\n result.frameworkRole = result.frameworkRole ?? 'drf_viewset';\n }\n }\n\n // --- Router registrations ---\n const registrations = extractRouterRegistrations(root);\n for (const reg of registrations) {\n result.edges!.push({\n edgeType: 'drf_router_registers',\n sourceSymbolId: `${filePath}::router_register_${reg.prefix}`,\n targetSymbolId: reg.viewsetName, // resolved in pass 2\n metadata: { prefix: reg.prefix, line: reg.line },\n });\n\n // Generate standard REST routes\n const routes = generateViewSetRoutes(reg.prefix);\n for (const route of routes) {\n result.routes!.push({\n ...route,\n line: reg.line,\n });\n }\n\n result.frameworkRole = result.frameworkRole ?? 'drf_router';\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n","/**\n * PydanticPlugin — Pydantic model plugin.\n *\n * Detects 'pydantic' in Python dependencies and extracts:\n * - BaseModel field → referenced type edges (pydantic_field_type)\n * - Model with from_attributes/orm_mode → ORM model hint (pydantic_from_orm)\n *\n * Supports Pydantic v1 (Config class with orm_mode) and v2 (model_config with\n * from_attributes).\n *\n * Uses tree-sitter-python for AST-based extraction.\n */\nimport { createRequire } from 'node:module';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, err } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n ResolveContext,\n EdgeTypeDeclaration,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\nimport { parseError } from '../../../../errors.js';\nimport { escapeRegExp } from '../../../../utils/security.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst PythonGrammar = require('tree-sitter-python');\n\n// tree-sitter types (CJS interop)\ntype TSNode = {\n type: string;\n text: string;\n startIndex: number;\n endIndex: number;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n namedChildCount: number;\n childCount: number;\n namedChildren: TSNode[];\n namedChild(index: number): TSNode | null;\n child(index: number): TSNode | null;\n childForFieldName(name: string): TSNode | null;\n parent: TSNode | null;\n isNamed: boolean;\n hasError: boolean;\n};\n\nlet parserInstance: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(): InstanceType<typeof Parser> {\n if (!parserInstance) {\n parserInstance = new Parser();\n parserInstance!.setLanguage(PythonGrammar);\n }\n return parserInstance!;\n}\n\n// ============================================================\n// Python dependency detection\n// ============================================================\n\nfunction hasPythonDep(rootPath: string, depName: string): boolean {\n for (const reqFile of ['requirements.txt', 'requirements/base.txt', 'requirements/prod.txt']) {\n try {\n const content = fs.readFileSync(path.join(rootPath, reqFile), 'utf-8');\n if (new RegExp(`^${escapeRegExp(depName)}\\\\b`, 'm').test(content)) return true;\n } catch { /* not found */ }\n }\n\n try {\n const content = fs.readFileSync(path.join(rootPath, 'pyproject.toml'), 'utf-8');\n if (content.includes(depName)) return true;\n } catch { /* not found */ }\n\n for (const f of ['setup.py', 'setup.cfg']) {\n try {\n const content = fs.readFileSync(path.join(rootPath, f), 'utf-8');\n if (content.includes(depName)) return true;\n } catch { /* not found */ }\n }\n\n try {\n const content = fs.readFileSync(path.join(rootPath, 'Pipfile'), 'utf-8');\n if (content.includes(depName)) return true;\n } catch { /* not found */ }\n\n return false;\n}\n\n// ============================================================\n// AST helpers\n// ============================================================\n\n/** Find all top-level class definitions (including decorated ones). */\nfunction findClassDefinitions(root: TSNode): TSNode[] {\n const classes: TSNode[] = [];\n for (const child of root.namedChildren) {\n if (child.type === 'class_definition') {\n classes.push(child);\n } else if (child.type === 'decorated_definition') {\n const inner = child.namedChildren.find(c => c.type === 'class_definition');\n if (inner) classes.push(inner);\n }\n }\n return classes;\n}\n\n/** Get superclass names from a class_definition node. */\nfunction getSuperclasses(classDef: TSNode): string[] {\n const argList = classDef.childForFieldName('superclasses');\n if (!argList) return [];\n const names: string[] = [];\n for (const child of argList.namedChildren) {\n if (child.type === 'identifier') {\n names.push(child.text);\n } else if (child.type === 'attribute') {\n names.push(child.text);\n }\n }\n return names;\n}\n\nfunction getClassName(classDef: TSNode): string {\n return classDef.childForFieldName('name')?.text ?? '';\n}\n\nfunction getClassBody(classDef: TSNode): TSNode | null {\n return classDef.childForFieldName('body');\n}\n\n/** Find an assignment in a block by target name. Returns the RHS node. */\nfunction findAssignment(body: TSNode, targetName: string): TSNode | null {\n for (const child of body.namedChildren) {\n if (child.type === 'expression_statement') {\n const expr = child.namedChildren[0];\n if (expr?.type === 'assignment') {\n const left = expr.childForFieldName('left');\n if (left?.type === 'identifier' && left.text === targetName) {\n return expr.childForFieldName('right');\n }\n }\n }\n }\n return null;\n}\n\n/** Find a nested class (like Config) inside a class body. */\nfunction findNestedClass(body: TSNode, name: string): TSNode | null {\n for (const child of body.namedChildren) {\n if (child.type === 'class_definition') {\n const n = child.childForFieldName('name');\n if (n?.text === name) return child;\n }\n }\n return null;\n}\n\nfunction shortName(name: string): string {\n const dot = name.lastIndexOf('.');\n return dot >= 0 ? name.slice(dot + 1) : name;\n}\n\n// ============================================================\n// Builtin type set (skip these for field_type edges)\n// ============================================================\n\nconst PYTHON_BUILTINS = new Set([\n 'str', 'int', 'float', 'bool', 'bytes', 'None', 'NoneType',\n 'dict', 'list', 'tuple', 'set', 'frozenset',\n 'Any', 'Optional', 'Union', 'Literal', 'ClassVar',\n 'List', 'Dict', 'Set', 'Tuple', 'FrozenSet', 'Sequence',\n 'Mapping', 'Iterable', 'Iterator', 'Callable', 'Type',\n 'Annotated', 'Final',\n 'datetime', 'date', 'time', 'timedelta', 'Decimal', 'UUID',\n 'EmailStr', 'HttpUrl', 'AnyUrl', 'AnyHttpUrl',\n 'constr', 'conint', 'confloat', 'conbytes', 'condecimal',\n 'PositiveInt', 'NegativeInt', 'PositiveFloat', 'NegativeFloat',\n 'StrictStr', 'StrictInt', 'StrictFloat', 'StrictBool',\n 'SecretStr', 'SecretBytes', 'FilePath', 'DirectoryPath',\n 'Json', 'PaymentCardNumber', 'IPvAnyAddress',\n]);\n\n// ============================================================\n// Pydantic model extraction\n// ============================================================\n\nconst PYDANTIC_BASES = new Set([\n 'BaseModel', 'pydantic.BaseModel',\n 'BaseSettings', 'pydantic.BaseSettings',\n 'GenericModel', 'pydantic.generics.GenericModel',\n]);\n\ninterface PydanticFieldRef {\n fieldName: string;\n typeName: string;\n line: number;\n}\n\ninterface PydanticModelInfo {\n className: string;\n fields: PydanticFieldRef[];\n hasFromAttributes: boolean;\n line: number;\n}\n\n/**\n * Extract type references from a type annotation node.\n * Handles: bare identifiers, subscripts like list[Item], Optional[Item], Union[A, B].\n */\nfunction extractTypeRefs(typeNode: TSNode): string[] {\n const refs: string[] = [];\n\n if (typeNode.type === 'identifier') {\n const name = typeNode.text;\n if (!PYTHON_BUILTINS.has(name)) {\n refs.push(name);\n }\n return refs;\n }\n\n if (typeNode.type === 'attribute') {\n const name = shortName(typeNode.text);\n if (!PYTHON_BUILTINS.has(name)) {\n refs.push(name);\n }\n return refs;\n }\n\n // list[Item], Optional[Item], dict[str, Item], etc.\n if (typeNode.type === 'subscript') {\n const base = typeNode.childForFieldName('value');\n const subscriptSlices = typeNode.namedChildren.filter(c => c !== base);\n\n // For wrapper types (Optional, List, etc.), recurse into subscript args\n const baseName = base?.text ?? '';\n if (PYTHON_BUILTINS.has(baseName) || PYTHON_BUILTINS.has(shortName(baseName))) {\n for (const slice of subscriptSlices) {\n refs.push(...extractTypeRefs(slice));\n }\n } else {\n // Custom generic like MyType[X] — the base itself is a type ref\n if (!PYTHON_BUILTINS.has(shortName(baseName))) {\n refs.push(shortName(baseName));\n }\n for (const slice of subscriptSlices) {\n refs.push(...extractTypeRefs(slice));\n }\n }\n return refs;\n }\n\n // Union via X | Y (binary_operator with |)\n if (typeNode.type === 'binary_operator') {\n const left = typeNode.childForFieldName('left');\n const right = typeNode.childForFieldName('right');\n if (left) refs.push(...extractTypeRefs(left));\n if (right) refs.push(...extractTypeRefs(right));\n return refs;\n }\n\n // Tuple of types in subscript args\n if (typeNode.type === 'tuple' || typeNode.type === 'expression_list') {\n for (const child of typeNode.namedChildren) {\n refs.push(...extractTypeRefs(child));\n }\n return refs;\n }\n\n return refs;\n}\n\n/**\n * Extract typed fields from a Pydantic BaseModel class body.\n * Looks for: `field_name: SomeType` or `field_name: SomeType = default`\n */\nfunction extractFieldAnnotations(body: TSNode): PydanticFieldRef[] {\n const fields: PydanticFieldRef[] = [];\n\n for (const child of body.namedChildren) {\n // type annotation: `name: Type`\n if (child.type === 'expression_statement') {\n const inner = child.namedChildren[0];\n if (!inner) continue;\n\n // `name: Type` (bare annotation)\n if (inner.type === 'type') {\n // tree-sitter-python wraps annotations in 'type' node\n // Actually this appears as expression_statement > type > ...\n // Let's handle the children\n continue;\n }\n\n // `name: Type = value` (assignment with type annotation)\n if (inner.type === 'assignment') {\n const left = inner.childForFieldName('left');\n const typeNode = inner.childForFieldName('type');\n if (left?.type === 'identifier' && typeNode) {\n const refs = extractTypeRefs(typeNode);\n for (const ref of refs) {\n fields.push({\n fieldName: left.text,\n typeName: ref,\n line: child.startPosition.row + 1,\n });\n }\n }\n }\n }\n\n // Annotated assignment without default: `name: Type`\n // tree-sitter-python represents this as `type` node inside `expression_statement`\n // Actually, Python `name: str` is parsed as:\n // expression_statement > type > identifier (the annotation)\n // But with value: `name: str = \"foo\"` is:\n // expression_statement > assignment (left=name, type=str, right=\"foo\")\n //\n // For bare annotation `name: Type`, tree-sitter uses 'type' node:\n if (child.type === 'type') {\n // The 'type' node in tree-sitter-python stores the annotation\n // Its children: identifier (name) and the type annotation\n // Actually tree-sitter-python has 'expression_statement' > 'type' where\n // the 'type' node contains the var name and annotation.\n // Let's handle it more carefully.\n continue;\n }\n }\n\n // Second pass: handle bare annotations via typed assignments\n // tree-sitter-python 0.25 parses `name: Type` as expression_statement with\n // a single child of type 'type' whose text is `name: Type`.\n // We need to use a different approach for these.\n for (const child of body.namedChildren) {\n if (child.type !== 'expression_statement') continue;\n const inner = child.namedChildren[0];\n if (!inner) continue;\n\n // tree-sitter-python: bare annotation `name: str` is parsed as\n // expression_statement > type (text = \"name: str\")\n // where type has child identifier = \"name\" and the annotation type child\n if (inner.type === 'type') {\n // The 'type' node has two children: the variable name and the type annotation\n // But actually in tree-sitter-python, `x: int` is parsed as:\n // expression_statement\n // type: (type\n // (identifier) ; the type annotation\n // )\n // And the variable name is stored elsewhere.\n // Let's use text parsing as a fallback for bare annotations.\n const text = child.text.trim();\n const match = text.match(/^(\\w+)\\s*:\\s*(.+)$/s);\n if (match) {\n const fieldName = match[1];\n const typeStr = match[2].trim();\n // Quick parse: extract non-builtin type names\n const typeNames = typeStr.match(/\\b[A-Z]\\w+/g) ?? [];\n for (const tn of typeNames) {\n if (!PYTHON_BUILTINS.has(tn)) {\n fields.push({\n fieldName,\n typeName: tn,\n line: child.startPosition.row + 1,\n });\n }\n }\n }\n }\n }\n\n return fields;\n}\n\n/**\n * Check if a Pydantic model has from_attributes=True (v2) or orm_mode=True (v1).\n */\nfunction hasFromAttributes(body: TSNode): boolean {\n // v2: model_config = ConfigDict(from_attributes=True)\n const configAssign = findAssignment(body, 'model_config');\n if (configAssign) {\n // Look for from_attributes=True in the call\n if (/from_attributes\\s*=\\s*True/.test(configAssign.text)) {\n return true;\n }\n }\n\n // v1: class Config: orm_mode = True\n const configClass = findNestedClass(body, 'Config');\n if (configClass) {\n const configBody = getClassBody(configClass);\n if (configBody) {\n const ormModeRhs = findAssignment(configBody, 'orm_mode');\n if (ormModeRhs?.text === 'True') {\n return true;\n }\n // Also check from_attributes in v2-style Config class\n const fromAttrRhs = findAssignment(configBody, 'from_attributes');\n if (fromAttrRhs?.text === 'True') {\n return true;\n }\n }\n }\n\n return false;\n}\n\nfunction extractPydanticModels(root: TSNode): PydanticModelInfo[] {\n const result: PydanticModelInfo[] = [];\n\n for (const classDef of findClassDefinitions(root)) {\n const supers = getSuperclasses(classDef);\n // Direct Pydantic base check + allow subclassing other models\n const isPydantic = supers.some(s => PYDANTIC_BASES.has(s));\n if (!isPydantic) continue;\n\n const className = getClassName(classDef);\n const body = getClassBody(classDef);\n if (!body) continue;\n\n const fields = extractFieldAnnotations(body);\n const fromAttr = hasFromAttributes(body);\n\n result.push({\n className,\n fields,\n hasFromAttributes: fromAttr,\n line: classDef.startPosition.row + 1,\n });\n }\n\n return result;\n}\n\n// ============================================================\n// Plugin class\n// ============================================================\n\nexport class PydanticPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'pydantic',\n version: '1.0.0',\n priority: 30,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n return hasPythonDep(ctx.rootPath, 'pydantic');\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'pydantic_field_type', category: 'pydantic', description: 'BaseModel field → referenced type' } as EdgeTypeDeclaration,\n { name: 'pydantic_from_orm', category: 'pydantic', description: 'Model with from_attributes → ORM model hint' } as EdgeTypeDeclaration,\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'python') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n edges: [],\n };\n\n let tree: { rootNode: TSNode };\n try {\n const parser = getParser();\n tree = parser.parse(source);\n } catch (e) {\n return err(parseError(filePath, `tree-sitter parse failed: ${e}`));\n }\n\n const root = tree.rootNode;\n const models = extractPydanticModels(root);\n\n for (const model of models) {\n // Field type references\n for (const field of model.fields) {\n result.edges!.push({\n edgeType: 'pydantic_field_type',\n sourceSymbolId: `${filePath}::${model.className}#class`,\n targetSymbolId: field.typeName, // resolved in pass 2\n metadata: {\n field: field.fieldName,\n line: field.line,\n },\n });\n }\n\n // ORM mode hint\n if (model.hasFromAttributes) {\n result.edges!.push({\n edgeType: 'pydantic_from_orm',\n sourceSymbolId: `${filePath}::${model.className}#class`,\n targetSymbolId: model.className, // placeholder — actual ORM model resolution in pass 2\n metadata: {\n hint: 'from_attributes',\n line: model.line,\n },\n });\n }\n\n result.frameworkRole = 'pydantic_model';\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n","/**\n * CeleryPlugin — Celery task queue plugin.\n *\n * Detects 'celery' in Python dependencies and extracts:\n * - @app.task / @celery.task / @shared_task decorated functions (celery_task_registered)\n * - beat_schedule configuration entries (celery_beat_schedule)\n * - .delay() and .apply_async() calls on known tasks (celery_dispatches)\n *\n * Uses tree-sitter-python for AST-based extraction.\n */\nimport { createRequire } from 'node:module';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, err } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n ResolveContext,\n EdgeTypeDeclaration,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\nimport { parseError } from '../../../../errors.js';\nimport { escapeRegExp } from '../../../../utils/security.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst PythonGrammar = require('tree-sitter-python');\n\n// tree-sitter types (CJS interop)\ntype TSNode = {\n type: string;\n text: string;\n startIndex: number;\n endIndex: number;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n namedChildCount: number;\n childCount: number;\n namedChildren: TSNode[];\n namedChild(index: number): TSNode | null;\n child(index: number): TSNode | null;\n childForFieldName(name: string): TSNode | null;\n parent: TSNode | null;\n isNamed: boolean;\n hasError: boolean;\n};\n\nlet parserInstance: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(): InstanceType<typeof Parser> {\n if (!parserInstance) {\n parserInstance = new Parser();\n parserInstance!.setLanguage(PythonGrammar);\n }\n return parserInstance!;\n}\n\n// ============================================================\n// Python dependency detection\n// ============================================================\n\nfunction hasPythonDep(rootPath: string, depName: string): boolean {\n for (const reqFile of ['requirements.txt', 'requirements/base.txt', 'requirements/prod.txt']) {\n try {\n const content = fs.readFileSync(path.join(rootPath, reqFile), 'utf-8');\n if (new RegExp(`^${escapeRegExp(depName)}\\\\b`, 'm').test(content)) return true;\n } catch { /* not found */ }\n }\n\n try {\n const content = fs.readFileSync(path.join(rootPath, 'pyproject.toml'), 'utf-8');\n if (content.includes(depName)) return true;\n } catch { /* not found */ }\n\n for (const f of ['setup.py', 'setup.cfg']) {\n try {\n const content = fs.readFileSync(path.join(rootPath, f), 'utf-8');\n if (content.includes(depName)) return true;\n } catch { /* not found */ }\n }\n\n try {\n const content = fs.readFileSync(path.join(rootPath, 'Pipfile'), 'utf-8');\n if (content.includes(depName)) return true;\n } catch { /* not found */ }\n\n return false;\n}\n\n// ============================================================\n// AST helpers\n// ============================================================\n\nfunction stripQuotes(s: string): string {\n return s.replace(/^[brufBRUF]*['\"]/, '').replace(/['\"]$/, '');\n}\n\n/** Walk all nodes of a given type. */\nfunction walkNodes(node: TSNode, type: string, visitor: (n: TSNode) => void): void {\n if (node.type === type) {\n visitor(node);\n }\n for (const child of node.namedChildren) {\n walkNodes(child, type, visitor);\n }\n}\n\n/** Walk all nodes, calling visitor for each. */\nfunction walkAll(node: TSNode, visitor: (n: TSNode) => void): void {\n visitor(node);\n for (const child of node.namedChildren) {\n walkAll(child, visitor);\n }\n}\n\n// ============================================================\n// Celery task extraction\n// ============================================================\n\ninterface CeleryTaskInfo {\n functionName: string;\n taskName: string | null; // explicit name from decorator arg\n line: number;\n}\n\n/**\n * Match decorator patterns:\n * - @app.task / @celery.task / @celery_app.task (attribute form)\n * - @app.task(name='...') / @celery.task(bind=True, name='...')\n * - @shared_task / @shared_task(name='...')\n */\nfunction isCeleryTaskDecorator(decoratorNode: TSNode): { isTask: boolean; taskName: string | null } {\n // decorator node's child is the actual expression\n const expr = decoratorNode.namedChildren[0];\n if (!expr) return { isTask: false, taskName: null };\n\n // Simple identifier: @shared_task\n if (expr.type === 'identifier' && expr.text === 'shared_task') {\n return { isTask: true, taskName: null };\n }\n\n // Attribute: @app.task or @celery.task\n if (expr.type === 'attribute') {\n const attrName = expr.childForFieldName('attribute');\n if (attrName?.text === 'task') {\n return { isTask: true, taskName: null };\n }\n }\n\n // Call form: @shared_task(...) or @app.task(...)\n if (expr.type === 'call') {\n const fn = expr.childForFieldName('function');\n let isTask = false;\n\n if (fn?.type === 'identifier' && fn.text === 'shared_task') {\n isTask = true;\n } else if (fn?.type === 'attribute') {\n const attrName = fn.childForFieldName('attribute');\n if (attrName?.text === 'task') {\n isTask = true;\n }\n }\n\n if (isTask) {\n // Extract name= keyword argument\n const args = expr.childForFieldName('arguments');\n if (args) {\n for (const arg of args.namedChildren) {\n if (arg.type === 'keyword_argument') {\n const nameNode = arg.childForFieldName('name');\n const valueNode = arg.childForFieldName('value');\n if (nameNode?.text === 'name' && valueNode?.type === 'string') {\n return { isTask: true, taskName: stripQuotes(valueNode.text) };\n }\n }\n }\n }\n return { isTask: true, taskName: null };\n }\n }\n\n return { isTask: false, taskName: null };\n}\n\nfunction extractCeleryTasks(root: TSNode): CeleryTaskInfo[] {\n const tasks: CeleryTaskInfo[] = [];\n\n for (const child of root.namedChildren) {\n if (child.type !== 'decorated_definition') continue;\n\n // Find the function inside the decorated_definition\n const funcDef = child.namedChildren.find(c => c.type === 'function_definition');\n if (!funcDef) continue;\n\n const funcName = funcDef.childForFieldName('name')?.text;\n if (!funcName) continue;\n\n // Check each decorator\n const decorators = child.namedChildren.filter(c => c.type === 'decorator');\n for (const dec of decorators) {\n const { isTask, taskName } = isCeleryTaskDecorator(dec);\n if (isTask) {\n tasks.push({\n functionName: funcName,\n taskName,\n line: child.startPosition.row + 1,\n });\n break; // one match is enough\n }\n }\n }\n\n return tasks;\n}\n\n// ============================================================\n// Beat schedule extraction\n// ============================================================\n\ninterface BeatScheduleEntry {\n entryName: string;\n taskName: string;\n line: number;\n}\n\n/**\n * Extract beat_schedule entries from:\n * app.conf.beat_schedule = { 'entry-name': { 'task': 'module.task_name', ... }, ... }\n * CELERY_BEAT_SCHEDULE = { ... } (Django settings style)\n *\n * Parses dictionary literal for task names.\n */\nfunction extractBeatSchedule(root: TSNode): BeatScheduleEntry[] {\n const entries: BeatScheduleEntry[] = [];\n\n walkAll(root, (node) => {\n if (node.type !== 'assignment') return;\n\n const left = node.childForFieldName('left');\n if (!left) return;\n\n // Match app.conf.beat_schedule or CELERY_BEAT_SCHEDULE or beat_schedule\n const target = left.text;\n const isBeatSchedule =\n target.endsWith('beat_schedule') ||\n target === 'CELERY_BEAT_SCHEDULE';\n if (!isBeatSchedule) return;\n\n const right = node.childForFieldName('right');\n if (!right || right.type !== 'dictionary') return;\n\n // Each top-level pair is an entry: 'entry-name': { 'task': '...', ... }\n for (const pair of right.namedChildren) {\n if (pair.type !== 'pair') continue;\n\n const keyNode = pair.childForFieldName('key');\n const valueNode = pair.childForFieldName('value');\n if (!keyNode || !valueNode) continue;\n\n const entryName = keyNode.type === 'string' ? stripQuotes(keyNode.text) : keyNode.text;\n\n // The value should be a dict containing 'task': 'some.task.name'\n if (valueNode.type !== 'dictionary') continue;\n\n for (const innerPair of valueNode.namedChildren) {\n if (innerPair.type !== 'pair') continue;\n\n const innerKey = innerPair.childForFieldName('key');\n const innerValue = innerPair.childForFieldName('value');\n if (!innerKey || !innerValue) continue;\n\n const k = innerKey.type === 'string' ? stripQuotes(innerKey.text) : innerKey.text;\n if (k === 'task' && innerValue.type === 'string') {\n const taskName = stripQuotes(innerValue.text);\n entries.push({\n entryName,\n taskName,\n line: pair.startPosition.row + 1,\n });\n }\n }\n }\n });\n\n return entries;\n}\n\n// ============================================================\n// Dispatch call extraction (.delay() / .apply_async())\n// ============================================================\n\ninterface DispatchCall {\n calledOn: string; // the identifier being called on\n method: 'delay' | 'apply_async';\n line: number;\n}\n\n/**\n * Find .delay() and .apply_async() calls.\n * Best-effort: only captures calls where the object is a simple identifier\n * (e.g., send_email.delay(), process_order.apply_async()).\n */\nfunction extractDispatchCalls(root: TSNode): DispatchCall[] {\n const dispatches: DispatchCall[] = [];\n\n walkAll(root, (node) => {\n if (node.type !== 'call') return;\n\n const fn = node.childForFieldName('function');\n if (!fn || fn.type !== 'attribute') return;\n\n const attrName = fn.childForFieldName('attribute')?.text;\n if (attrName !== 'delay' && attrName !== 'apply_async') return;\n\n const obj = fn.childForFieldName('object');\n if (!obj) return;\n\n // Only capture simple identifiers or dotted names\n if (obj.type === 'identifier' || obj.type === 'attribute') {\n dispatches.push({\n calledOn: obj.text,\n method: attrName as 'delay' | 'apply_async',\n line: node.startPosition.row + 1,\n });\n }\n });\n\n return dispatches;\n}\n\n// ============================================================\n// Plugin class\n// ============================================================\n\nexport class CeleryPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'celery',\n version: '1.0.0',\n priority: 30,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n return hasPythonDep(ctx.rootPath, 'celery');\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'celery_task_registered', category: 'celery', description: '@app.task / @shared_task → function' } as EdgeTypeDeclaration,\n { name: 'celery_beat_schedule', category: 'celery', description: 'Beat schedule entry → task' } as EdgeTypeDeclaration,\n { name: 'celery_dispatches', category: 'celery', description: '.delay() / .apply_async() → task' } as EdgeTypeDeclaration,\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'python') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n edges: [],\n routes: [],\n };\n\n let tree: { rootNode: TSNode };\n try {\n const parser = getParser();\n tree = parser.parse(source);\n } catch (e) {\n return err(parseError(filePath, `tree-sitter parse failed: ${e}`));\n }\n\n const root = tree.rootNode;\n\n // --- Celery tasks ---\n const tasks = extractCeleryTasks(root);\n const knownTaskFunctions = new Set<string>();\n\n for (const task of tasks) {\n const taskName = task.taskName ?? task.functionName;\n knownTaskFunctions.add(task.functionName);\n\n result.edges!.push({\n edgeType: 'celery_task_registered',\n sourceSymbolId: `${filePath}::${task.functionName}#function`,\n targetSymbolId: `${filePath}::${task.functionName}#function`,\n metadata: {\n taskName,\n explicitName: task.taskName ?? undefined,\n line: task.line,\n },\n });\n\n // Store as route-like entity for discoverability\n result.routes!.push({\n method: 'TASK',\n uri: taskName,\n name: task.functionName,\n line: task.line,\n });\n\n result.frameworkRole = 'celery_tasks';\n }\n\n // --- Beat schedule ---\n const beatEntries = extractBeatSchedule(root);\n for (const entry of beatEntries) {\n result.edges!.push({\n edgeType: 'celery_beat_schedule',\n sourceSymbolId: `${filePath}::beat_schedule_${entry.entryName}`,\n targetSymbolId: entry.taskName, // resolved in pass 2 by task name\n metadata: {\n entryName: entry.entryName,\n taskName: entry.taskName,\n line: entry.line,\n },\n });\n\n result.frameworkRole = result.frameworkRole ?? 'celery_beat';\n }\n\n // --- Dispatch calls (.delay / .apply_async) ---\n const dispatches = extractDispatchCalls(root);\n for (const dispatch of dispatches) {\n // Best-effort: only emit edge when the callee is a known task in the same file\n if (knownTaskFunctions.has(dispatch.calledOn)) {\n result.edges!.push({\n edgeType: 'celery_dispatches',\n sourceSymbolId: filePath, // file-level — caller context unknown without scope analysis\n targetSymbolId: `${filePath}::${dispatch.calledOn}#function`,\n metadata: {\n method: dispatch.method,\n line: dispatch.line,\n },\n });\n } else {\n // Cross-file dispatch — emit with unresolved target\n result.edges!.push({\n edgeType: 'celery_dispatches',\n sourceSymbolId: filePath,\n targetSymbolId: dispatch.calledOn, // resolved in pass 2\n metadata: {\n method: dispatch.method,\n line: dispatch.line,\n crossFile: true,\n },\n });\n }\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n","/**\n * FastAPIPlugin — Framework plugin for FastAPI (Python).\n *\n * Extracts:\n * - Route decorators: @app.get('/path'), @router.post('/path'), etc.\n * - Depends() dependency injection in function parameters\n * - Response model annotations on route decorators\n * - app.include_router() mounts\n *\n * Uses tree-sitter-python for AST parsing.\n */\nimport { createRequire } from 'node:module';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, err } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawRoute,\n EdgeTypeDeclaration,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\nimport { parseError } from '../../../../errors.js';\nimport { escapeRegExp } from '../../../../utils/security.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst PythonGrammar = require('tree-sitter-python');\n\n/** HTTP methods recognized on FastAPI route decorators. */\nconst HTTP_METHODS = new Set(['get', 'post', 'put', 'delete', 'patch', 'options', 'head']);\n\n/**\n * Check if a Python project has a given package in its dependencies.\n * Reads pyproject.toml parsed deps and requirements.txt from the ProjectContext,\n * falling back to reading files from disk.\n */\nfunction hasPythonDep(ctx: ProjectContext, pkg: string): boolean {\n const lowerPkg = pkg.toLowerCase();\n\n // Check parsed pyproject.toml deps\n if (ctx.pyprojectToml) {\n const deps = ctx.pyprojectToml._parsedDeps as string[] | undefined;\n if (deps?.includes(lowerPkg)) return true;\n }\n\n // Check parsed requirements.txt\n if (ctx.requirementsTxt?.includes(lowerPkg)) return true;\n\n // Fallback: read from disk\n try {\n const pyprojectPath = path.join(ctx.rootPath, 'pyproject.toml');\n const content = fs.readFileSync(pyprojectPath, 'utf-8');\n const re = new RegExp(`[\"']${escapeRegExp(pkg)}[>=<\\\\[!~\\\\s\"']`, 'i');\n if (re.test(content)) return true;\n } catch { /* not found */ }\n\n try {\n const reqPath = path.join(ctx.rootPath, 'requirements.txt');\n const content = fs.readFileSync(reqPath, 'utf-8');\n const re = new RegExp(`^${escapeRegExp(pkg)}\\\\b`, 'im');\n if (re.test(content)) return true;\n } catch { /* not found */ }\n\n return false;\n}\n\nexport class FastAPIPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'fastapi',\n version: '1.0.0',\n priority: 10,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n return hasPythonDep(ctx, 'fastapi');\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'fastapi_route', category: 'fastapi', description: 'FastAPI route decorator → handler function' },\n { name: 'fastapi_depends', category: 'fastapi', description: 'FastAPI Depends() dependency injection' },\n { name: 'fastapi_request_model', category: 'fastapi', description: 'Route handler → Pydantic request model' },\n { name: 'fastapi_response_model', category: 'fastapi', description: 'Route decorator → Pydantic response model' },\n { name: 'fastapi_router_mounts', category: 'fastapi', description: 'app.include_router() mount' },\n ] satisfies EdgeTypeDeclaration[],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'python') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n // Quick check — skip files that don't mention fastapi-related patterns\n if (\n !source.includes('fastapi') &&\n !source.includes('FastAPI') &&\n !source.includes('APIRouter') &&\n !source.includes('@app.') &&\n !source.includes('@router.')\n ) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n routes: [],\n edges: [],\n warnings: [],\n };\n\n try {\n const parser = new Parser();\n parser.setLanguage(PythonGrammar);\n const tree = parser.parse(source);\n const root = tree.rootNode;\n\n this.extractRoutes(root, source, filePath, result);\n this.extractRouterMounts(root, source, filePath, result);\n } catch (e: unknown) {\n return err(parseError(filePath, `FastAPI parse error: ${e instanceof Error ? e.message : String(e)}`));\n }\n\n if (result.routes!.length > 0 || result.edges!.length > 0) {\n result.frameworkRole = 'fastapi_routes';\n }\n\n return ok(result);\n }\n\n /**\n * Extract route decorators from decorated_definition nodes.\n *\n * Patterns:\n * @app.get(\"/path\")\n * @app.post(\"/path\", response_model=Foo)\n * @router.put(\"/path\")\n */\n private extractRoutes(\n root: any,\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n const decoratedDefs = this.findAllByType(root, 'decorated_definition');\n\n for (const decoratedDef of decoratedDefs) {\n // The function_definition is a child of the decorated_definition\n const funcDef = decoratedDef.children.find(\n (c: any) => c.type === 'function_definition',\n );\n if (!funcDef) continue;\n\n const funcName = funcDef.childForFieldName('name')?.text ?? 'unknown';\n const parameters = funcDef.childForFieldName('parameters');\n\n // Iterate decorators\n for (const child of decoratedDef.children) {\n if (child.type !== 'decorator') continue;\n\n const decoratorExpr = child.children.find(\n (c: any) => c.type === 'call' || c.type === 'attribute',\n );\n if (!decoratorExpr) continue;\n\n // Resolve the call expression: @app.get(\"/path\") or @router.post(\"/path\", ...)\n let callNode: any = null;\n if (decoratorExpr.type === 'call') {\n callNode = decoratorExpr;\n }\n if (!callNode) continue;\n\n const funcRef = callNode.childForFieldName('function');\n if (!funcRef || funcRef.type !== 'attribute') continue;\n\n const methodName = funcRef.childForFieldName('attribute')?.text;\n if (!methodName || !HTTP_METHODS.has(methodName)) continue;\n\n // Extract URI from the first positional argument\n const args = callNode.childForFieldName('arguments');\n if (!args) continue;\n\n const uri = this.extractFirstStringArg(args);\n if (!uri) continue;\n\n // Extract response_model keyword argument\n const responseModel = this.extractKeywordArg(args, 'response_model');\n\n const route: RawRoute = {\n method: methodName.toUpperCase(),\n uri,\n controllerSymbolId: funcName,\n line: funcDef.startPosition.row + 1,\n };\n result.routes!.push(route);\n\n // Emit fastapi_route edge\n result.edges!.push({\n edgeType: 'fastapi_route',\n metadata: {\n method: route.method,\n uri: route.uri,\n handler: funcName,\n filePath,\n line: route.line,\n },\n });\n\n // Emit fastapi_response_model edge if present\n if (responseModel) {\n result.edges!.push({\n edgeType: 'fastapi_response_model',\n metadata: {\n handler: funcName,\n responseModel,\n filePath,\n },\n });\n }\n\n // Extract Depends() from function parameters\n if (parameters) {\n this.extractDepends(parameters, funcName, filePath, result);\n }\n\n // Extract Pydantic request model from type-annotated parameters\n if (parameters) {\n this.extractRequestModels(parameters, funcName, filePath, result);\n }\n }\n }\n }\n\n /**\n * Extract Depends(some_func) from function parameters.\n *\n * Pattern: param: Type = Depends(get_db)\n * In the AST: default_parameter → default value is call with function named \"Depends\"\n */\n private extractDepends(\n parameters: any,\n funcName: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n for (const param of parameters.children) {\n if (param.type !== 'default_parameter' && param.type !== 'typed_default_parameter') continue;\n\n // Find the default value (the last significant child)\n const defaultValue = param.childForFieldName('value') ??\n param.children[param.children.length - 1];\n if (!defaultValue || defaultValue.type !== 'call') continue;\n\n const callFunc = defaultValue.childForFieldName('function');\n if (!callFunc) continue;\n\n // Check for Depends() or Depends\n const callFuncName = callFunc.text;\n if (callFuncName !== 'Depends') continue;\n\n // Extract the dependency function name from the first argument\n const callArgs = defaultValue.childForFieldName('arguments');\n if (!callArgs) continue;\n\n const depTarget = this.getFirstArgText(callArgs);\n if (!depTarget) continue;\n\n result.edges!.push({\n edgeType: 'fastapi_depends',\n metadata: {\n handler: funcName,\n dependency: depTarget,\n filePath,\n },\n });\n }\n }\n\n /**\n * Extract Pydantic request models from type annotations in parameters.\n *\n * Pattern: async def create_item(item: ItemCreate):\n * We look for typed_parameter nodes where the annotation is a capitalized identifier\n * (likely a Pydantic model). We skip basic types like str, int, float, bool, etc.\n */\n private extractRequestModels(\n parameters: any,\n funcName: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n const builtinTypes = new Set([\n 'str', 'int', 'float', 'bool', 'bytes', 'list', 'dict', 'tuple',\n 'set', 'frozenset', 'None', 'Any', 'Optional', 'List', 'Dict',\n 'Request', 'Response', 'HTTPException',\n ]);\n\n for (const param of parameters.children) {\n if (param.type !== 'typed_parameter' && param.type !== 'typed_default_parameter') continue;\n\n const annotation = param.childForFieldName('type');\n if (!annotation) continue;\n\n const typeName = annotation.text;\n // Skip builtin types and lowercase names (path params, query params)\n if (!typeName || builtinTypes.has(typeName) || /^[a-z]/.test(typeName)) continue;\n // Skip generic types like Optional[X], List[X]\n if (typeName.includes('[')) continue;\n\n result.edges!.push({\n edgeType: 'fastapi_request_model',\n metadata: {\n handler: funcName,\n requestModel: typeName,\n filePath,\n },\n });\n }\n }\n\n /**\n * Extract app.include_router(router, prefix='/api/v1') calls.\n */\n private extractRouterMounts(\n root: any,\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n const calls = this.findAllByType(root, 'call');\n\n for (const call of calls) {\n const funcRef = call.childForFieldName('function');\n if (!funcRef || funcRef.type !== 'attribute') continue;\n\n const attr = funcRef.childForFieldName('attribute')?.text;\n if (attr !== 'include_router') continue;\n\n const args = call.childForFieldName('arguments');\n if (!args) continue;\n\n const routerName = this.getFirstArgText(args);\n const prefix = this.extractKeywordArg(args, 'prefix');\n const tags = this.extractKeywordArg(args, 'tags');\n\n if (routerName) {\n result.edges!.push({\n edgeType: 'fastapi_router_mounts',\n metadata: {\n router: routerName,\n prefix: prefix ?? '',\n tags: tags ?? '',\n filePath,\n line: call.startPosition.row + 1,\n },\n });\n }\n }\n }\n\n // ─── Tree-sitter helpers ───────────────────────────────────────────\n\n /** Recursively find all nodes of a given type. */\n private findAllByType(node: any, type: string): any[] {\n const results: any[] = [];\n if (node.type === type) results.push(node);\n for (const child of node.children ?? []) {\n results.push(...this.findAllByType(child, type));\n }\n return results;\n }\n\n /** Get the text of the first positional string argument in an argument_list. */\n private extractFirstStringArg(args: any): string | null {\n for (const child of args.children ?? []) {\n if (child.type === 'string') {\n return this.unquote(child.text);\n }\n // Handle concatenated_string\n if (child.type === 'concatenated_string') {\n return this.unquote(child.children[0]?.text ?? '');\n }\n }\n return null;\n }\n\n /** Get the text of the first positional (non-keyword) argument. */\n private getFirstArgText(args: any): string | null {\n for (const child of args.children ?? []) {\n if (child.type === 'keyword_argument' || child.type === '(' || child.type === ')' || child.type === ',') continue;\n return child.text;\n }\n return null;\n }\n\n /** Extract a keyword argument value as text. */\n private extractKeywordArg(args: any, name: string): string | null {\n for (const child of args.children ?? []) {\n if (child.type !== 'keyword_argument') continue;\n const key = child.childForFieldName('name')?.text;\n if (key !== name) continue;\n const value = child.childForFieldName('value');\n if (!value) continue;\n if (value.type === 'string') return this.unquote(value.text);\n return value.text;\n }\n return null;\n }\n\n /** Remove quotes from a Python string literal. */\n private unquote(s: string): string {\n // Handle triple-quoted, f-strings, etc.\n let text = s;\n // Strip leading f/b/r prefixes\n text = text.replace(/^[fFbBrRuU]+/, '');\n if (text.startsWith('\"\"\"') || text.startsWith(\"'''\")) {\n return text.slice(3, -3);\n }\n if (text.startsWith('\"') || text.startsWith(\"'\")) {\n return text.slice(1, -1);\n }\n return text;\n }\n}\n","/**\n * FlaskPlugin — Framework plugin for Flask (Python).\n *\n * Extracts:\n * - Route decorators: @app.route('/path', methods=['GET', 'POST'])\n * - Blueprint routes: @bp.route('/path')\n * - Blueprint registration: app.register_blueprint(bp, url_prefix='/api')\n * - Before-request hooks: @app.before_request\n * - Error handlers: @app.errorhandler(404)\n *\n * Uses tree-sitter-python for AST parsing.\n */\nimport { createRequire } from 'node:module';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, err } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawRoute,\n EdgeTypeDeclaration,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\nimport { parseError } from '../../../../errors.js';\nimport { escapeRegExp } from '../../../../utils/security.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst PythonGrammar = require('tree-sitter-python');\n\n/** Default HTTP method when none specified in @app.route(). */\nconst DEFAULT_METHODS = ['GET'];\n\n/**\n * Check if a Python project has a given package in its dependencies.\n */\nfunction hasPythonDep(ctx: ProjectContext, pkg: string): boolean {\n const lowerPkg = pkg.toLowerCase();\n\n if (ctx.pyprojectToml) {\n const deps = ctx.pyprojectToml._parsedDeps as string[] | undefined;\n if (deps?.includes(lowerPkg)) return true;\n }\n\n if (ctx.requirementsTxt?.includes(lowerPkg)) return true;\n\n try {\n const pyprojectPath = path.join(ctx.rootPath, 'pyproject.toml');\n const content = fs.readFileSync(pyprojectPath, 'utf-8');\n const re = new RegExp(`[\"']${escapeRegExp(pkg)}[>=<\\\\[!~\\\\s\"']`, 'i');\n if (re.test(content)) return true;\n } catch { /* not found */ }\n\n try {\n const reqPath = path.join(ctx.rootPath, 'requirements.txt');\n const content = fs.readFileSync(reqPath, 'utf-8');\n const re = new RegExp(`^${escapeRegExp(pkg)}\\\\b`, 'im');\n if (re.test(content)) return true;\n } catch { /* not found */ }\n\n return false;\n}\n\nexport class FlaskPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'flask',\n version: '1.0.0',\n priority: 10,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n return hasPythonDep(ctx, 'flask');\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'flask_route', category: 'flask', description: 'Flask route decorator → handler function' },\n { name: 'flask_blueprint_mounts', category: 'flask', description: 'app.register_blueprint() mount' },\n { name: 'flask_before_request', category: 'flask', description: '@app.before_request hook' },\n { name: 'flask_error_handler', category: 'flask', description: '@app.errorhandler() registration' },\n ] satisfies EdgeTypeDeclaration[],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'python') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n // Quick check — skip files without flask-related patterns\n if (\n !source.includes('flask') &&\n !source.includes('Flask') &&\n !source.includes('Blueprint') &&\n !source.includes('@app.') &&\n !source.includes('@bp.') &&\n !source.includes('.route(')\n ) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n routes: [],\n edges: [],\n warnings: [],\n };\n\n try {\n const parser = new Parser();\n parser.setLanguage(PythonGrammar);\n const tree = parser.parse(source);\n const root = tree.rootNode;\n\n this.extractRoutes(root, source, filePath, result);\n this.extractBlueprintMounts(root, source, filePath, result);\n this.extractBeforeRequestHooks(root, source, filePath, result);\n this.extractErrorHandlers(root, source, filePath, result);\n } catch (e: unknown) {\n return err(parseError(filePath, `Flask parse error: ${e instanceof Error ? e.message : String(e)}`));\n }\n\n if (result.routes!.length > 0 || result.edges!.length > 0) {\n result.frameworkRole = 'flask_routes';\n }\n\n return ok(result);\n }\n\n /**\n * Extract route decorators from decorated_definition nodes.\n *\n * Patterns:\n * @app.route('/path') → GET\n * @app.route('/path', methods=['GET', 'POST']) → GET, POST\n * @bp.route('/path') → GET\n */\n private extractRoutes(\n root: any,\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n const decoratedDefs = this.findAllByType(root, 'decorated_definition');\n\n for (const decoratedDef of decoratedDefs) {\n const funcDef = decoratedDef.children.find(\n (c: any) => c.type === 'function_definition',\n );\n if (!funcDef) continue;\n\n const funcName = funcDef.childForFieldName('name')?.text ?? 'unknown';\n\n for (const child of decoratedDef.children) {\n if (child.type !== 'decorator') continue;\n\n const callNode = child.children.find((c: any) => c.type === 'call');\n if (!callNode) continue;\n\n const funcRef = callNode.childForFieldName('function');\n if (!funcRef || funcRef.type !== 'attribute') continue;\n\n const attrName = funcRef.childForFieldName('attribute')?.text;\n if (attrName !== 'route') continue;\n\n const args = callNode.childForFieldName('arguments');\n if (!args) continue;\n\n // Extract URI from first positional string argument\n const uri = this.extractFirstStringArg(args);\n if (!uri) continue;\n\n // Extract methods keyword argument: methods=['GET', 'POST']\n const methods = this.extractMethodsArg(args) ?? DEFAULT_METHODS;\n\n // Emit one RawRoute per method\n for (const method of methods) {\n const route: RawRoute = {\n method: method.toUpperCase(),\n uri,\n controllerSymbolId: funcName,\n line: funcDef.startPosition.row + 1,\n };\n result.routes!.push(route);\n\n result.edges!.push({\n edgeType: 'flask_route',\n metadata: {\n method: route.method,\n uri: route.uri,\n handler: funcName,\n filePath,\n line: route.line,\n },\n });\n }\n }\n }\n }\n\n /**\n * Extract app.register_blueprint(bp, url_prefix='/api') calls.\n */\n private extractBlueprintMounts(\n root: any,\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n const calls = this.findAllByType(root, 'call');\n\n for (const call of calls) {\n const funcRef = call.childForFieldName('function');\n if (!funcRef || funcRef.type !== 'attribute') continue;\n\n const attr = funcRef.childForFieldName('attribute')?.text;\n if (attr !== 'register_blueprint') continue;\n\n const args = call.childForFieldName('arguments');\n if (!args) continue;\n\n const blueprintName = this.getFirstArgText(args);\n const urlPrefix = this.extractKeywordArg(args, 'url_prefix');\n\n if (blueprintName) {\n result.edges!.push({\n edgeType: 'flask_blueprint_mounts',\n metadata: {\n blueprint: blueprintName,\n urlPrefix: urlPrefix ?? '',\n filePath,\n line: call.startPosition.row + 1,\n },\n });\n }\n }\n }\n\n /**\n * Extract @app.before_request / @bp.before_request hooks.\n */\n private extractBeforeRequestHooks(\n root: any,\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n const decoratedDefs = this.findAllByType(root, 'decorated_definition');\n\n for (const decoratedDef of decoratedDefs) {\n const funcDef = decoratedDef.children.find(\n (c: any) => c.type === 'function_definition',\n );\n if (!funcDef) continue;\n\n const funcName = funcDef.childForFieldName('name')?.text ?? 'unknown';\n\n for (const child of decoratedDef.children) {\n if (child.type !== 'decorator') continue;\n\n // @app.before_request is an attribute access, not a call\n const attrNode = child.children.find((c: any) => c.type === 'attribute');\n if (!attrNode) continue;\n\n const attrName = attrNode.childForFieldName('attribute')?.text;\n if (attrName !== 'before_request' && attrName !== 'before_app_request') continue;\n\n result.edges!.push({\n edgeType: 'flask_before_request',\n metadata: {\n handler: funcName,\n hookType: attrName,\n filePath,\n line: funcDef.startPosition.row + 1,\n },\n });\n }\n }\n }\n\n /**\n * Extract @app.errorhandler(404) / @app.errorhandler(Exception) decorators.\n */\n private extractErrorHandlers(\n root: any,\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n const decoratedDefs = this.findAllByType(root, 'decorated_definition');\n\n for (const decoratedDef of decoratedDefs) {\n const funcDef = decoratedDef.children.find(\n (c: any) => c.type === 'function_definition',\n );\n if (!funcDef) continue;\n\n const funcName = funcDef.childForFieldName('name')?.text ?? 'unknown';\n\n for (const child of decoratedDef.children) {\n if (child.type !== 'decorator') continue;\n\n const callNode = child.children.find((c: any) => c.type === 'call');\n if (!callNode) continue;\n\n const funcRef = callNode.childForFieldName('function');\n if (!funcRef || funcRef.type !== 'attribute') continue;\n\n const attrName = funcRef.childForFieldName('attribute')?.text;\n if (attrName !== 'errorhandler') continue;\n\n const args = callNode.childForFieldName('arguments');\n const errorCode = args ? this.getFirstArgText(args) : 'unknown';\n\n result.edges!.push({\n edgeType: 'flask_error_handler',\n metadata: {\n handler: funcName,\n errorCode: errorCode ?? 'unknown',\n filePath,\n line: funcDef.startPosition.row + 1,\n },\n });\n }\n }\n }\n\n // ─── Tree-sitter helpers ───────────────────────────────────────────\n\n private findAllByType(node: any, type: string): any[] {\n const results: any[] = [];\n if (node.type === type) results.push(node);\n for (const child of node.children ?? []) {\n results.push(...this.findAllByType(child, type));\n }\n return results;\n }\n\n private extractFirstStringArg(args: any): string | null {\n for (const child of args.children ?? []) {\n if (child.type === 'string') {\n return this.unquote(child.text);\n }\n if (child.type === 'concatenated_string') {\n return this.unquote(child.children[0]?.text ?? '');\n }\n }\n return null;\n }\n\n private getFirstArgText(args: any): string | null {\n for (const child of args.children ?? []) {\n if (child.type === 'keyword_argument' || child.type === '(' || child.type === ')' || child.type === ',') continue;\n return child.text;\n }\n return null;\n }\n\n private extractKeywordArg(args: any, name: string): string | null {\n for (const child of args.children ?? []) {\n if (child.type !== 'keyword_argument') continue;\n const key = child.childForFieldName('name')?.text;\n if (key !== name) continue;\n const value = child.childForFieldName('value');\n if (!value) continue;\n if (value.type === 'string') return this.unquote(value.text);\n return value.text;\n }\n return null;\n }\n\n /**\n * Extract methods=['GET', 'POST'] keyword argument.\n * Returns an array of method strings, or null if not found.\n */\n private extractMethodsArg(args: any): string[] | null {\n for (const child of args.children ?? []) {\n if (child.type !== 'keyword_argument') continue;\n const key = child.childForFieldName('name')?.text;\n if (key !== 'methods') continue;\n const value = child.childForFieldName('value');\n if (!value) continue;\n\n // value should be a list: ['GET', 'POST']\n if (value.type === 'list') {\n const methods: string[] = [];\n for (const item of value.children ?? []) {\n if (item.type === 'string') {\n methods.push(this.unquote(item.text));\n }\n }\n return methods.length > 0 ? methods : null;\n }\n }\n return null;\n }\n\n private unquote(s: string): string {\n let text = s;\n text = text.replace(/^[fFbBrRuU]+/, '');\n if (text.startsWith('\"\"\"') || text.startsWith(\"'''\")) {\n return text.slice(3, -3);\n }\n if (text.startsWith('\"') || text.startsWith(\"'\")) {\n return text.slice(1, -1);\n }\n return text;\n }\n}\n","/**\n * SQLAlchemyPlugin — Framework plugin for SQLAlchemy ORM (Python).\n *\n * Extracts:\n * - Declarative models: classes inheriting Base/DeclarativeBase with __tablename__\n * - ForeignKey constraints: mapped_column(ForeignKey('table.id')) and Column(ForeignKey(...))\n * - relationship() definitions → cross-model edges\n * - Alembic migrations: op.create_table, op.add_column, op.drop_table\n *\n * Uses tree-sitter-python for AST parsing.\n */\nimport { createRequire } from 'node:module';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, err } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawOrmModel,\n RawOrmAssociation,\n EdgeTypeDeclaration,\n RawMigration,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\nimport { parseError } from '../../../../errors.js';\nimport { escapeRegExp } from '../../../../utils/security.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst PythonGrammar = require('tree-sitter-python');\n\n/** Known base classes for SQLAlchemy declarative models. */\nconst MODEL_BASES = new Set([\n 'Base', 'DeclarativeBase', 'DeclarativeBaseNoMeta',\n 'MappedAsDataclass', 'db.Model',\n]);\n\n/**\n * Check if a Python project has a given package in its dependencies.\n */\nfunction hasPythonDep(ctx: ProjectContext, pkg: string): boolean {\n const lowerPkg = pkg.toLowerCase();\n\n if (ctx.pyprojectToml) {\n const deps = ctx.pyprojectToml._parsedDeps as string[] | undefined;\n if (deps?.includes(lowerPkg)) return true;\n }\n\n if (ctx.requirementsTxt?.includes(lowerPkg)) return true;\n\n try {\n const pyprojectPath = path.join(ctx.rootPath, 'pyproject.toml');\n const content = fs.readFileSync(pyprojectPath, 'utf-8');\n const re = new RegExp(`[\"']${escapeRegExp(pkg)}[>=<\\\\[!~\\\\s\"']`, 'i');\n if (re.test(content)) return true;\n } catch { /* not found */ }\n\n try {\n const reqPath = path.join(ctx.rootPath, 'requirements.txt');\n const content = fs.readFileSync(reqPath, 'utf-8');\n const re = new RegExp(`^${escapeRegExp(pkg)}\\\\b`, 'im');\n if (re.test(content)) return true;\n } catch { /* not found */ }\n\n return false;\n}\n\nexport class SQLAlchemyPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'sqlalchemy',\n version: '1.0.0',\n priority: 10,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n return hasPythonDep(ctx, 'sqlalchemy');\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'sqla_relationship', category: 'sqlalchemy', description: 'SQLAlchemy relationship() between models' },\n { name: 'sqla_fk', category: 'sqlalchemy', description: 'SQLAlchemy ForeignKey constraint' },\n { name: 'sqla_migrates', category: 'sqlalchemy', description: 'Alembic migration operation on a table' },\n ] satisfies EdgeTypeDeclaration[],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'python') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n ormModels: [],\n ormAssociations: [],\n edges: [],\n migrations: [],\n warnings: [],\n };\n\n // Check if this is an Alembic migration file\n const isAlembicMigration =\n filePath.includes('alembic/versions/') ||\n filePath.includes('migrations/versions/');\n\n if (isAlembicMigration) {\n // Quick check for migration operations\n if (source.includes('op.create_table') || source.includes('op.add_column') || source.includes('op.drop_table')) {\n try {\n const parser = new Parser();\n parser.setLanguage(PythonGrammar);\n const tree = parser.parse(source);\n this.extractAlembicMigrations(tree.rootNode, source, filePath, result);\n } catch (e: unknown) {\n return err(parseError(filePath, `SQLAlchemy migration parse error: ${e instanceof Error ? e.message : String(e)}`));\n }\n result.frameworkRole = 'alembic_migration';\n return ok(result);\n }\n return ok(result);\n }\n\n // Quick check — skip files that don't look like SQLAlchemy models\n if (\n !source.includes('Column') &&\n !source.includes('mapped_column') &&\n !source.includes('relationship') &&\n !source.includes('ForeignKey') &&\n !source.includes('__tablename__') &&\n !source.includes('DeclarativeBase') &&\n !source.includes('declarative_base')\n ) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n try {\n const parser = new Parser();\n parser.setLanguage(PythonGrammar);\n const tree = parser.parse(source);\n const root = tree.rootNode;\n\n this.extractModels(root, source, filePath, result);\n } catch (e: unknown) {\n return err(parseError(filePath, `SQLAlchemy parse error: ${e instanceof Error ? e.message : String(e)}`));\n }\n\n return ok(result);\n }\n\n /**\n * Extract SQLAlchemy model classes from the AST.\n *\n * Detects class definitions that:\n * 1. Inherit from Base, DeclarativeBase, db.Model, etc.\n * 2. Have a __tablename__ assignment in their body\n */\n private extractModels(\n root: any,\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n const classDefs = this.findAllTopLevelClasses(root);\n\n for (const classDef of classDefs) {\n const className = classDef.childForFieldName('name')?.text;\n if (!className) continue;\n\n // Check superclasses\n const superclasses = classDef.childForFieldName('superclasses');\n if (!superclasses) continue;\n\n const bases = this.extractSuperclassNames(superclasses);\n const isSQLAlchemyModel = bases.some((b) => MODEL_BASES.has(b));\n if (!isSQLAlchemyModel) continue;\n\n // Get class body\n const body = classDef.childForFieldName('body');\n if (!body) continue;\n\n // Look for __tablename__ assignment\n const tableName = this.extractTableName(body);\n if (!tableName) continue;\n\n // This is a SQLAlchemy model\n const fields = this.extractModelFields(body, source);\n const foreignKeys = this.extractForeignKeys(body, source, className, tableName);\n const relationships = this.extractRelationships(body, source, className);\n\n const model: RawOrmModel = {\n name: className,\n orm: 'sqlalchemy',\n collectionOrTable: tableName,\n fields,\n metadata: {\n filePath,\n bases: bases.join(', '),\n line: classDef.startPosition.row + 1,\n },\n };\n\n result.ormModels!.push(model);\n result.frameworkRole = 'sqlalchemy_model';\n\n // Add foreign key edges\n for (const fk of foreignKeys) {\n result.edges!.push({\n edgeType: 'sqla_fk',\n metadata: {\n sourceModel: className,\n sourceTable: tableName,\n targetTable: fk.targetTable,\n targetColumn: fk.targetColumn,\n columnName: fk.columnName,\n filePath,\n },\n });\n }\n\n // Add relationship edges and ORM associations\n for (const rel of relationships) {\n result.edges!.push({\n edgeType: 'sqla_relationship',\n metadata: {\n sourceModel: className,\n targetModel: rel.targetModel,\n attributeName: rel.attributeName,\n backPopulates: rel.backPopulates,\n backRef: rel.backRef,\n uselist: rel.uselist,\n filePath,\n },\n });\n\n result.ormAssociations!.push({\n sourceModelName: className,\n targetModelName: rel.targetModel,\n kind: rel.uselist === false ? 'one_to_one' : 'one_to_many',\n options: {\n backPopulates: rel.backPopulates,\n backRef: rel.backRef,\n },\n line: rel.line,\n });\n }\n }\n }\n\n /**\n * Extract Alembic migration operations from a migration file.\n *\n * Detects:\n * - op.create_table('name', ...)\n * - op.add_column('table', ...)\n * - op.drop_table('name')\n */\n private extractAlembicMigrations(\n root: any,\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n const calls = this.findAllByType(root, 'call');\n\n // Try to extract revision timestamp from the file name\n const fileBaseName = path.basename(filePath);\n const timestampMatch = fileBaseName.match(/^(\\d+)_/);\n const timestamp = timestampMatch ? timestampMatch[1] : undefined;\n\n for (const call of calls) {\n const funcRef = call.childForFieldName('function');\n if (!funcRef || funcRef.type !== 'attribute') continue;\n\n const object = funcRef.childForFieldName('object')?.text;\n if (object !== 'op') continue;\n\n const method = funcRef.childForFieldName('attribute')?.text;\n if (!method) continue;\n\n const args = call.childForFieldName('arguments');\n if (!args) continue;\n\n let operation: 'create' | 'alter' | 'drop' | null = null;\n if (method === 'create_table') operation = 'create';\n else if (method === 'add_column' || method === 'alter_column' || method === 'drop_column') operation = 'alter';\n else if (method === 'drop_table') operation = 'drop';\n else continue;\n\n const tableName = this.extractFirstStringArg(args);\n if (!tableName) continue;\n\n const migration: RawMigration = {\n tableName,\n operation,\n timestamp,\n };\n\n result.migrations!.push(migration);\n\n result.edges!.push({\n edgeType: 'sqla_migrates',\n metadata: {\n operation,\n tableName,\n method,\n filePath,\n line: call.startPosition.row + 1,\n },\n });\n }\n }\n\n // ─── Model extraction helpers ──────────────────────────────────────\n\n /** Find all class_definition nodes (including inside decorated_definition). */\n private findAllTopLevelClasses(root: any): any[] {\n const classes: any[] = [];\n for (const child of root.children ?? []) {\n if (child.type === 'class_definition') {\n classes.push(child);\n } else if (child.type === 'decorated_definition') {\n const innerClass = child.children.find((c: any) => c.type === 'class_definition');\n if (innerClass) classes.push(innerClass);\n }\n }\n return classes;\n }\n\n /** Extract superclass names from an argument_list node. */\n private extractSuperclassNames(superclasses: any): string[] {\n const names: string[] = [];\n for (const child of superclasses.children ?? []) {\n if (child.type === 'identifier') {\n names.push(child.text);\n } else if (child.type === 'attribute') {\n names.push(child.text);\n }\n }\n return names;\n }\n\n /** Extract __tablename__ = 'table_name' from a class body. */\n private extractTableName(body: any): string | null {\n for (const stmt of body.children ?? []) {\n if (stmt.type !== 'expression_statement') continue;\n const assignment = stmt.children.find((c: any) => c.type === 'assignment');\n if (!assignment) continue;\n\n const left = assignment.childForFieldName('left');\n if (!left || left.text !== '__tablename__') continue;\n\n const right = assignment.childForFieldName('right');\n if (!right || right.type !== 'string') continue;\n\n return this.unquote(right.text);\n }\n return null;\n }\n\n /**\n * Extract model field definitions from the class body.\n *\n * Patterns:\n * name: Mapped[str] = mapped_column(String(50))\n * name = Column(String(50), nullable=False)\n */\n private extractModelFields(body: any, source: string): Record<string, unknown>[] {\n const fields: Record<string, unknown>[] = [];\n\n for (const stmt of body.children ?? []) {\n if (stmt.type !== 'expression_statement') continue;\n\n // Handle both assignment and type_alias_statement\n const assignment = stmt.children.find(\n (c: any) => c.type === 'assignment',\n );\n if (!assignment) continue;\n\n const left = assignment.childForFieldName('left');\n if (!left) continue;\n\n const fieldName = left.text;\n // Skip dunder and private attributes\n if (fieldName.startsWith('_')) continue;\n\n const right = assignment.childForFieldName('right');\n if (!right) continue;\n\n // Check if it's a Column() or mapped_column() call\n const callFunc = right.type === 'call'\n ? right.childForFieldName('function')?.text\n : null;\n\n if (callFunc === 'Column' || callFunc === 'mapped_column') {\n fields.push({\n name: fieldName,\n definition: right.text,\n line: stmt.startPosition.row + 1,\n });\n } else if (callFunc === 'relationship') {\n // Skip relationships — handled separately\n continue;\n }\n }\n\n // Also handle annotated assignments: name: Mapped[str] = mapped_column(...)\n for (const stmt of body.children ?? []) {\n // Check for typed assignments that are a different node type\n if (stmt.type === 'type_alias_statement') continue;\n\n // Look for patterns like: name: Mapped[str] = mapped_column(...)\n // These may appear as expression_statement > assignment with type annotation\n // OR as standalone typed assignment nodes\n // tree-sitter-python may represent these differently\n }\n\n return fields;\n }\n\n /**\n * Extract ForeignKey references from Column/mapped_column calls.\n *\n * Patterns:\n * user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))\n * user_id = Column(Integer, ForeignKey('users.id'))\n */\n private extractForeignKeys(\n body: any,\n source: string,\n modelName: string,\n tableName: string,\n ): Array<{ columnName: string; targetTable: string; targetColumn: string }> {\n const fks: Array<{ columnName: string; targetTable: string; targetColumn: string }> = [];\n\n // Find all ForeignKey() calls within the class body\n const fkCalls = this.findAllByType(body, 'call');\n\n for (const call of fkCalls) {\n const funcRef = call.childForFieldName('function');\n if (!funcRef) continue;\n\n const funcName = funcRef.text;\n if (funcName !== 'ForeignKey') continue;\n\n const args = call.childForFieldName('arguments');\n if (!args) continue;\n\n const fkTarget = this.extractFirstStringArg(args);\n if (!fkTarget) continue;\n\n // Parse 'table.column' format\n const parts = fkTarget.split('.');\n if (parts.length !== 2) continue;\n\n // Walk up to find the column name (the assignment target)\n const columnName = this.findParentColumnName(call, body);\n\n fks.push({\n columnName: columnName ?? 'unknown',\n targetTable: parts[0],\n targetColumn: parts[1],\n });\n }\n\n return fks;\n }\n\n /**\n * Extract relationship() calls from the class body.\n *\n * Patterns:\n * items: Mapped[List[\"Item\"]] = relationship(back_populates=\"order\")\n * items = relationship('Item', back_populates='order')\n * items = relationship('Item', backref='order')\n */\n private extractRelationships(\n body: any,\n source: string,\n modelName: string,\n ): Array<{\n attributeName: string;\n targetModel: string;\n backPopulates: string | null;\n backRef: string | null;\n uselist: boolean | null;\n line: number;\n }> {\n const rels: Array<{\n attributeName: string;\n targetModel: string;\n backPopulates: string | null;\n backRef: string | null;\n uselist: boolean | null;\n line: number;\n }> = [];\n\n for (const stmt of body.children ?? []) {\n if (stmt.type !== 'expression_statement') continue;\n\n const assignment = stmt.children.find(\n (c: any) => c.type === 'assignment',\n );\n if (!assignment) continue;\n\n const left = assignment.childForFieldName('left');\n const right = assignment.childForFieldName('right');\n if (!left || !right || right.type !== 'call') continue;\n\n const funcRef = right.childForFieldName('function');\n if (!funcRef) continue;\n if (funcRef.text !== 'relationship') continue;\n\n const attrName = left.text;\n const args = right.childForFieldName('arguments');\n if (!args) continue;\n\n // First arg is the target model name (string)\n const targetModel = this.extractFirstStringArg(args) ??\n this.getFirstArgText(args) ??\n 'Unknown';\n\n const backPopulates = this.extractKeywordArg(args, 'back_populates');\n const backRef = this.extractKeywordArg(args, 'backref');\n const uselistStr = this.extractKeywordArg(args, 'uselist');\n const uselist = uselistStr === 'False' ? false : uselistStr === 'True' ? true : null;\n\n rels.push({\n attributeName: attrName,\n targetModel: targetModel.replace(/['\"]/g, ''),\n backPopulates,\n backRef,\n uselist,\n line: stmt.startPosition.row + 1,\n });\n }\n\n return rels;\n }\n\n /**\n * Walk up from a ForeignKey() call to find the parent column assignment name.\n */\n private findParentColumnName(fkCall: any, body: any): string | null {\n // Search through body statements to find which assignment contains this FK call\n for (const stmt of body.children ?? []) {\n if (stmt.type !== 'expression_statement') continue;\n const assignment = stmt.children.find((c: any) => c.type === 'assignment');\n if (!assignment) continue;\n\n // Check if this assignment's right-hand side contains the FK call\n const right = assignment.childForFieldName('right');\n if (!right) continue;\n\n if (this.nodeContains(right, fkCall)) {\n const left = assignment.childForFieldName('left');\n return left?.text ?? null;\n }\n }\n return null;\n }\n\n /** Check if a node contains a specific descendant (by identity). */\n private nodeContains(parent: any, target: any): boolean {\n if (parent.id === target.id) return true;\n for (const child of parent.children ?? []) {\n if (this.nodeContains(child, target)) return true;\n }\n return false;\n }\n\n // ─── Tree-sitter helpers ───────────────────────────────────────────\n\n private findAllByType(node: any, type: string): any[] {\n const results: any[] = [];\n if (node.type === type) results.push(node);\n for (const child of node.children ?? []) {\n results.push(...this.findAllByType(child, type));\n }\n return results;\n }\n\n private extractFirstStringArg(args: any): string | null {\n for (const child of args.children ?? []) {\n if (child.type === 'string') {\n return this.unquote(child.text);\n }\n if (child.type === 'concatenated_string') {\n return this.unquote(child.children[0]?.text ?? '');\n }\n }\n return null;\n }\n\n private getFirstArgText(args: any): string | null {\n for (const child of args.children ?? []) {\n if (child.type === 'keyword_argument' || child.type === '(' || child.type === ')' || child.type === ',') continue;\n return child.text;\n }\n return null;\n }\n\n private extractKeywordArg(args: any, name: string): string | null {\n for (const child of args.children ?? []) {\n if (child.type !== 'keyword_argument') continue;\n const key = child.childForFieldName('name')?.text;\n if (key !== name) continue;\n const value = child.childForFieldName('value');\n if (!value) continue;\n if (value.type === 'string') return this.unquote(value.text);\n return value.text;\n }\n return null;\n }\n\n private unquote(s: string): string {\n let text = s;\n text = text.replace(/^[fFbBrRuU]+/, '');\n if (text.startsWith('\"\"\"') || text.startsWith(\"'''\")) {\n return text.slice(3, -3);\n }\n if (text.startsWith('\"') || text.startsWith(\"'\")) {\n return text.slice(1, -1);\n }\n return text;\n }\n}\n","/**\n * Spring Boot Framework Plugin — extracts routes, DI, JPA entities.\n */\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin, PluginManifest, ProjectContext, FileParseResult, RawEdge, RawRoute,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\n\nexport class SpringPlugin implements FrameworkPlugin {\n manifest: PluginManifest = { name: 'spring', version: '1.0.0', priority: 50 };\n\n detect(ctx: ProjectContext): boolean {\n const hasSpringFiles = ctx.configFiles.some((f) =>\n /pom\\.xml|build\\.gradle(\\.kts)?|application\\.(properties|ya?ml)/.test(f),\n );\n return hasSpringFiles;\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'spring_route', category: 'http', description: 'Spring MVC/REST route mapping' },\n { name: 'spring_injects', category: 'di', description: 'Spring dependency injection' },\n { name: 'spring_entity_relation', category: 'orm', description: 'JPA entity relationship' },\n { name: 'spring_component_scan', category: 'framework', description: 'Component scan scope' },\n { name: 'spring_config_value', category: 'config', description: '@Value injection' },\n ],\n };\n }\n\n extractNodes(filePath: string, content: Buffer, language: string): TraceMcpResult<FileParseResult> {\n if (language !== 'java' && language !== 'kotlin') return ok({ status: 'ok', symbols: [] });\n\n const source = content.toString('utf-8');\n const result: FileParseResult = { status: 'ok', symbols: [], edges: [], routes: [] };\n\n if (/@(?:RestController|Controller)\\b/.test(source)) {\n result.frameworkRole = 'controller';\n this.extractRoutes(source, filePath, result);\n this.extractInjections(source, filePath, result);\n } else if (/@Entity\\b/.test(source)) {\n result.frameworkRole = 'entity';\n this.extractEntityRelations(source, filePath, result);\n } else if (/@Service\\b/.test(source)) {\n result.frameworkRole = 'service';\n this.extractInjections(source, filePath, result);\n } else if (/@Repository\\b/.test(source)) {\n result.frameworkRole = 'repository';\n this.extractInjections(source, filePath, result);\n } else if (/@Component\\b/.test(source)) {\n result.frameworkRole = 'component';\n this.extractInjections(source, filePath, result);\n } else if (/@Configuration\\b/.test(source)) {\n result.frameworkRole = 'configuration';\n this.extractInjections(source, filePath, result);\n } else {\n return ok({ status: 'ok', symbols: [] });\n }\n\n return ok(result);\n }\n\n private extractRoutes(source: string, filePath: string, result: FileParseResult): void {\n // Class-level @RequestMapping prefix\n const classMappingMatch = source.match(/@RequestMapping\\s*\\(\\s*(?:value\\s*=\\s*)?[\"']([^\"']+)[\"']/);\n const classPrefix = classMappingMatch?.[1] ?? '';\n\n const mappings: { annotation: string; method: string }[] = [\n { annotation: 'GetMapping', method: 'GET' },\n { annotation: 'PostMapping', method: 'POST' },\n { annotation: 'PutMapping', method: 'PUT' },\n { annotation: 'DeleteMapping', method: 'DELETE' },\n { annotation: 'PatchMapping', method: 'PATCH' },\n ];\n\n for (const { annotation, method } of mappings) {\n const re = new RegExp(`@${annotation}\\\\s*(?:\\\\(\\\\s*(?:value\\\\s*=\\\\s*)?[\"']([^\"']*)[\"']\\\\s*\\\\))?`, 'g');\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n const path = m[1] ?? '';\n const uri = normalizePath(classPrefix + '/' + path);\n result.routes!.push({ method, uri, line: source.substring(0, m.index).split('\\n').length });\n }\n }\n\n // @RequestMapping with method parameter\n const rmRe = /@RequestMapping\\s*\\([^)]*(?:value\\s*=\\s*)?[\"']([^\"']+)[\"'][^)]*method\\s*=\\s*RequestMethod\\.(\\w+)/g;\n let rm: RegExpExecArray | null;\n while ((rm = rmRe.exec(source)) !== null) {\n const uri = normalizePath(classPrefix + '/' + rm[1]);\n result.routes!.push({ method: rm[2], uri, line: source.substring(0, rm.index).split('\\n').length });\n }\n }\n\n private extractInjections(source: string, filePath: string, result: FileParseResult): void {\n // @Autowired fields\n const autowiredRe = /@Autowired\\s+(?:private\\s+|protected\\s+|public\\s+)?(\\w+)\\s+(\\w+)/g;\n let m: RegExpExecArray | null;\n while ((m = autowiredRe.exec(source)) !== null) {\n result.edges!.push({\n edgeType: 'spring_injects',\n metadata: { targetType: m[1], fieldName: m[2], style: 'field' },\n });\n }\n\n // Constructor injection (Kotlin-style or Java record-style)\n const constructorRe = /(?:constructor|public\\s+\\w+)\\s*\\(([^)]+)\\)/g;\n let cm: RegExpExecArray | null;\n while ((cm = constructorRe.exec(source)) !== null) {\n const params = cm[1].split(',');\n for (const param of params) {\n const parts = param.trim().split(/\\s+/);\n if (parts.length >= 2) {\n const typeName = parts[parts.length - 2];\n if (typeName[0] === typeName[0].toUpperCase() && typeName !== 'String' && typeName !== 'Integer') {\n result.edges!.push({\n edgeType: 'spring_injects',\n metadata: { targetType: typeName, style: 'constructor' },\n });\n }\n }\n }\n }\n\n // @Value\n const valueRe = /@Value\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g;\n let vm: RegExpExecArray | null;\n while ((vm = valueRe.exec(source)) !== null) {\n result.edges!.push({\n edgeType: 'spring_config_value',\n metadata: { expression: vm[1] },\n });\n }\n }\n\n private extractEntityRelations(source: string, filePath: string, result: FileParseResult): void {\n const relations = ['OneToMany', 'ManyToOne', 'OneToOne', 'ManyToMany'];\n for (const rel of relations) {\n const re = new RegExp(`@${rel}[^)]*(?:targetEntity\\\\s*=\\\\s*(\\\\w+))?[^)]*\\\\)\\\\s*(?:private\\\\s+|protected\\\\s+)?(?:[\\\\w<>]+\\\\s+)?(\\\\w+)`, 'g');\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n result.edges!.push({\n edgeType: 'spring_entity_relation',\n metadata: { kind: rel, targetEntity: m[1] ?? null, fieldName: m[2] },\n });\n }\n }\n }\n}\n\nfunction normalizePath(path: string): string {\n return '/' + path.replace(/\\/+/g, '/').replace(/^\\/|\\/$/g, '');\n}\n","/**\n * Rails Framework Plugin — routes, ActiveRecord models, controllers, migrations.\n */\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin, PluginManifest, ProjectContext, FileParseResult, RawEdge, RawRoute, RawMigration,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\n\nexport class RailsPlugin implements FrameworkPlugin {\n manifest: PluginManifest = { name: 'rails', version: '1.0.0', priority: 50 };\n\n detect(ctx: ProjectContext): boolean {\n return ctx.configFiles.some((f) =>\n f === 'Gemfile' || f === 'config/routes.rb' || f === 'config/application.rb',\n );\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'rails_route', category: 'http', description: 'Rails route mapping' },\n { name: 'rails_has_many', category: 'orm', description: 'ActiveRecord has_many' },\n { name: 'rails_belongs_to', category: 'orm', description: 'ActiveRecord belongs_to' },\n { name: 'rails_has_one', category: 'orm', description: 'ActiveRecord has_one' },\n { name: 'rails_habtm', category: 'orm', description: 'ActiveRecord has_and_belongs_to_many' },\n { name: 'rails_before_action', category: 'middleware', description: 'Controller before_action callback' },\n { name: 'rails_validates', category: 'validation', description: 'Model validation' },\n ],\n };\n }\n\n extractNodes(filePath: string, content: Buffer, language: string): TraceMcpResult<FileParseResult> {\n if (language !== 'ruby') return ok({ status: 'ok', symbols: [] });\n\n const source = content.toString('utf-8');\n const result: FileParseResult = { status: 'ok', symbols: [], edges: [], routes: [], migrations: [] };\n\n if (filePath.match(/config\\/routes/)) {\n this.extractRoutes(source, result);\n } else if (/< ApplicationRecord\\b|< ActiveRecord::Base\\b/.test(source)) {\n result.frameworkRole = 'model';\n this.extractModelAssociations(source, result);\n this.extractValidations(source, result);\n } else if (/< ApplicationController\\b|< ActionController::Base\\b/.test(source)) {\n result.frameworkRole = 'controller';\n this.extractCallbacks(source, result);\n } else if (/< ActiveRecord::Migration\\b/.test(source)) {\n result.frameworkRole = 'migration';\n this.extractMigrations(source, filePath, result);\n } else {\n return ok({ status: 'ok', symbols: [] });\n }\n\n return ok(result);\n }\n\n private extractRoutes(source: string, result: FileParseResult): void {\n const prefixStack: string[] = [];\n\n const lines = source.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // namespace :api do\n const nsMatch = line.match(/namespace\\s+:(\\w+)/);\n if (nsMatch) {\n prefixStack.push(nsMatch[1]);\n continue;\n }\n\n // scope '/api' do\n const scopeMatch = line.match(/scope\\s+['\"]([^'\"]+)['\"]/);\n if (scopeMatch) {\n prefixStack.push(scopeMatch[1].replace(/^\\//, ''));\n continue;\n }\n\n if (/^\\s*end\\s*$/.test(lines[i]) && prefixStack.length > 0) {\n prefixStack.pop();\n continue;\n }\n\n const prefix = prefixStack.length > 0 ? '/' + prefixStack.join('/') : '';\n\n // resources :users\n const resourcesMatch = line.match(/resources?\\s+:(\\w+)/);\n if (resourcesMatch) {\n const name = resourcesMatch[0].startsWith('resources') ? resourcesMatch[1] : resourcesMatch[1];\n const isPlural = resourcesMatch[0].startsWith('resources');\n const base = `${prefix}/${name}`;\n\n if (isPlural) {\n result.routes!.push(\n { method: 'GET', uri: base, line: i + 1 },\n { method: 'GET', uri: `${base}/:id`, line: i + 1 },\n { method: 'POST', uri: base, line: i + 1 },\n { method: 'PUT', uri: `${base}/:id`, line: i + 1 },\n { method: 'PATCH', uri: `${base}/:id`, line: i + 1 },\n { method: 'DELETE', uri: `${base}/:id`, line: i + 1 },\n );\n } else {\n result.routes!.push(\n { method: 'GET', uri: base, line: i + 1 },\n { method: 'POST', uri: base, line: i + 1 },\n { method: 'PUT', uri: base, line: i + 1 },\n { method: 'PATCH', uri: base, line: i + 1 },\n { method: 'DELETE', uri: base, line: i + 1 },\n );\n }\n continue;\n }\n\n // get '/about', to: 'pages#about'\n const verbMatch = line.match(/(?:get|post|put|patch|delete)\\s+['\"]([^'\"]+)['\"]/);\n if (verbMatch) {\n const method = line.match(/^(get|post|put|patch|delete)/i)?.[1]?.toUpperCase() ?? 'GET';\n const uri = prefix + verbMatch[1];\n const toMatch = line.match(/to:\\s*['\"](\\w+)#(\\w+)['\"]/);\n result.routes!.push({\n method,\n uri,\n line: i + 1,\n ...(toMatch ? { name: `${toMatch[1]}#${toMatch[2]}` } : {}),\n });\n continue;\n }\n\n // root to: 'home#index'\n const rootMatch = line.match(/root\\s+(?:to:\\s*)?['\"](\\w+)#(\\w+)['\"]/);\n if (rootMatch) {\n result.routes!.push({ method: 'GET', uri: '/', line: i + 1, name: `${rootMatch[1]}#${rootMatch[2]}` });\n }\n }\n }\n\n private extractModelAssociations(source: string, result: FileParseResult): void {\n const assocTypes: { pattern: string; edgeType: string }[] = [\n { pattern: 'has_many', edgeType: 'rails_has_many' },\n { pattern: 'belongs_to', edgeType: 'rails_belongs_to' },\n { pattern: 'has_one', edgeType: 'rails_has_one' },\n { pattern: 'has_and_belongs_to_many', edgeType: 'rails_habtm' },\n ];\n\n for (const { pattern, edgeType } of assocTypes) {\n const re = new RegExp(`${pattern}\\\\s+:(\\\\w+)`, 'g');\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n result.edges!.push({\n edgeType,\n metadata: { target: m[1] },\n });\n }\n }\n }\n\n private extractValidations(source: string, result: FileParseResult): void {\n const re = /validates?\\s+:(\\w+)(?:\\s*,\\s*(.+?))?$/gm;\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n result.edges!.push({\n edgeType: 'rails_validates',\n metadata: { field: m[1], rules: m[2]?.trim() },\n });\n }\n }\n\n private extractCallbacks(source: string, result: FileParseResult): void {\n const callbacks = ['before_action', 'after_action', 'around_action', 'skip_before_action'];\n for (const cb of callbacks) {\n const re = new RegExp(`${cb}\\\\s+:(\\\\w+)`, 'g');\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n result.edges!.push({\n edgeType: 'rails_before_action',\n metadata: { callback: cb, method: m[1] },\n });\n }\n }\n }\n\n private extractMigrations(source: string, filePath: string, result: FileParseResult): void {\n // Timestamp from filename: 20230101120000_create_users.rb\n const tsMatch = filePath.match(/(\\d{14})_/);\n const timestamp = tsMatch?.[1];\n\n const createRe = /create_table\\s+:(\\w+)|create_table\\s+['\"](\\w+)['\"]/g;\n let m: RegExpExecArray | null;\n while ((m = createRe.exec(source)) !== null) {\n const tableName = m[1] ?? m[2];\n const columns: Record<string, unknown>[] = [];\n\n // Find column definitions after create_table up to next end\n const afterTable = source.substring(m.index);\n const colRe = /t\\.(\\w+)\\s+:(\\w+)/g;\n let cm: RegExpExecArray | null;\n while ((cm = colRe.exec(afterTable)) !== null) {\n if (cm[1] === 'end') break;\n columns.push({ name: cm[2], type: cm[1] });\n }\n\n result.migrations!.push({\n tableName,\n operation: 'create',\n columns,\n timestamp,\n });\n }\n\n const addColRe = /add_column\\s+:(\\w+)\\s*,\\s*:(\\w+)\\s*,\\s*:(\\w+)/g;\n while ((m = addColRe.exec(source)) !== null) {\n result.migrations!.push({\n tableName: m[1],\n operation: 'alter',\n columns: [{ name: m[2], type: m[3] }],\n timestamp,\n });\n }\n\n const dropRe = /drop_table\\s+[:\"'](\\w+)/g;\n while ((m = dropRe.exec(source)) !== null) {\n result.migrations!.push({ tableName: m[1], operation: 'drop', timestamp });\n }\n }\n}\n","/**\n * DjangoPlugin — Framework plugin for Django applications.\n *\n * Orchestrates model, URL, signal, admin, form, and view extraction.\n *\n * Supports Django 2.x–5.x:\n * - Models: models.Model subclasses with ForeignKey/M2M/O2O relationships\n * - URLs: path(), re_path(), url(), include(), DRF routers\n * - Views: CBVs (ListView, DetailView, etc.) with model/template detection\n * - Admin: @admin.register(), admin.site.register()\n * - Signals: @receiver(), signal.connect()\n * - Forms: ModelForm with Meta.model\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n ResolveContext,\n EdgeTypeDeclaration,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\nimport { escapeRegExp } from '../../../../utils/security.js';\nimport { extractDjangoModels } from './models.js';\nimport { extractUrlPatterns } from './urls.js';\nimport { extractSignalConnections } from './signals.js';\nimport { extractAdminRegistrations } from './admin.js';\n\nexport class DjangoPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'django',\n version: '1.0.0',\n priority: 10,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n // Check for manage.py in config files\n if (ctx.configFiles.some((f) => path.basename(f) === 'manage.py')) {\n return true;\n }\n\n // Check for manage.py on disk\n try {\n fs.accessSync(path.join(ctx.rootPath, 'manage.py'), fs.constants.F_OK);\n return true;\n } catch {\n // continue to check pyproject.toml\n }\n\n // Check pyproject.toml for django dependency\n try {\n const pyprojectPath = path.join(ctx.rootPath, 'pyproject.toml');\n const content = fs.readFileSync(pyprojectPath, 'utf-8');\n if (/django/i.test(content) && /dependencies|requires/i.test(content)) {\n return true;\n }\n } catch {\n // continue to check requirements files\n }\n\n // Check requirements.txt or requirements/*.txt\n try {\n const reqPath = path.join(ctx.rootPath, 'requirements.txt');\n const content = fs.readFileSync(reqPath, 'utf-8');\n if (/^django(?:==|>=|<=|~=|!=|\\[|\\s|$)/im.test(content)) {\n return true;\n }\n } catch {\n // no requirements.txt\n }\n\n // Check setup.py / setup.cfg\n try {\n const setupPath = path.join(ctx.rootPath, 'setup.py');\n const content = fs.readFileSync(setupPath, 'utf-8');\n if (/['\"]django['\"]/i.test(content)) {\n return true;\n }\n } catch {\n // not found\n }\n\n return false;\n }\n\n registerSchema() {\n const edgeTypes: EdgeTypeDeclaration[] = [\n { name: 'django_url_routes_to', category: 'django', description: 'URL pattern routes to view' },\n { name: 'django_includes_urls', category: 'django', description: 'URL config includes another URL module' },\n { name: 'django_view_uses_model', category: 'django', description: 'View references a model' },\n { name: 'django_view_template', category: 'django', description: 'View renders a template' },\n { name: 'django_signal_receiver', category: 'django', description: 'Signal receiver connected to signal+sender' },\n { name: 'django_admin_registers', category: 'django', description: 'Admin class registers a model' },\n { name: 'django_form_meta_model', category: 'django', description: 'ModelForm Meta.model reference' },\n ];\n return { edgeTypes };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'python') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n edges: [],\n routes: [],\n ormModels: [],\n ormAssociations: [],\n warnings: [],\n };\n\n // --- Models ---\n const modelResults = extractDjangoModels(source, filePath);\n if (modelResults.length > 0) {\n result.frameworkRole = 'model';\n for (const mr of modelResults) {\n result.ormModels!.push(mr.model);\n result.ormAssociations!.push(...mr.associations);\n }\n }\n\n // --- URL patterns ---\n if (this.isUrlFile(filePath)) {\n const urlResult = extractUrlPatterns(source, filePath);\n result.routes = urlResult.routes;\n result.edges!.push(...urlResult.edges);\n result.frameworkRole = result.frameworkRole ?? 'url_config';\n if (urlResult.warnings.length > 0) {\n result.warnings!.push(...urlResult.warnings);\n }\n }\n\n // --- Views (CBV detection) ---\n this.extractViewEdges(source, filePath, result);\n\n // --- Signals ---\n const signalEdges = extractSignalConnections(source, filePath);\n if (signalEdges.length > 0) {\n result.edges!.push(...signalEdges);\n result.frameworkRole = result.frameworkRole ?? 'signals';\n }\n\n // --- Admin ---\n if (this.isAdminFile(filePath)) {\n const adminEdges = extractAdminRegistrations(source, filePath);\n if (adminEdges.length > 0) {\n result.edges!.push(...adminEdges);\n result.frameworkRole = result.frameworkRole ?? 'admin';\n }\n }\n\n // --- Forms (ModelForm Meta.model) ---\n this.extractFormEdges(source, filePath, result);\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n const files = ctx.getAllFiles();\n\n for (const file of files) {\n if (file.language !== 'python') continue;\n\n let source: string;\n try {\n source = fs.readFileSync(\n path.resolve(ctx.rootPath, file.path),\n 'utf-8',\n );\n } catch {\n continue;\n }\n\n // Resolve model relationship edges\n this.resolveModelEdges(source, file, ctx, edges);\n\n // Resolve admin → model edges\n this.resolveAdminEdges(source, file, ctx, edges);\n\n // Resolve signal → model edges\n this.resolveSignalEdges(source, file, ctx, edges);\n\n // Resolve form → model edges\n this.resolveFormEdges(source, file, ctx, edges);\n\n // Resolve view → model edges\n this.resolveViewModelEdges(source, file, ctx, edges);\n }\n\n return ok(edges);\n }\n\n // ============================================================\n // View extraction (CBV)\n // ============================================================\n\n /**\n * Extract class-based view information.\n * Detects model, template_name, queryset from CBV subclasses.\n */\n private extractViewEdges(\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n const cbvBases = [\n 'ListView', 'DetailView', 'CreateView', 'UpdateView', 'DeleteView',\n 'FormView', 'TemplateView', 'RedirectView',\n 'GenericAPIView', 'ModelViewSet', 'ReadOnlyModelViewSet',\n 'ListAPIView', 'RetrieveAPIView', 'CreateAPIView',\n 'UpdateAPIView', 'DestroyAPIView', 'ListCreateAPIView',\n 'RetrieveUpdateAPIView', 'RetrieveDestroyAPIView',\n 'RetrieveUpdateDestroyAPIView',\n ];\n\n const basesPattern = cbvBases.map(escapeRegExp).join('|');\n const classRegex = new RegExp(\n `class\\\\s+(\\\\w+)\\\\s*\\\\((?:[\\\\w.,\\\\s]*(?:${basesPattern})[\\\\w.,\\\\s]*)\\\\)\\\\s*:`,\n 'g',\n );\n\n let classMatch: RegExpExecArray | null;\n while ((classMatch = classRegex.exec(source)) !== null) {\n const className = classMatch[1];\n const bodyStart = classMatch.index + classMatch[0].length;\n const body = this.extractIndentedBody(source, bodyStart);\n if (!body) continue;\n\n result.frameworkRole = result.frameworkRole ?? 'view';\n\n // Extract model = ModelName\n const modelMatch = body.match(/model\\s*=\\s*(\\w+)/);\n if (modelMatch) {\n result.edges!.push({\n edgeType: 'django_view_uses_model',\n metadata: {\n viewClass: className,\n modelName: modelMatch[1],\n filePath,\n },\n });\n }\n\n // Extract queryset = Model.objects...\n const querysetMatch = body.match(/queryset\\s*=\\s*(\\w+)\\.objects/);\n if (querysetMatch && !modelMatch) {\n result.edges!.push({\n edgeType: 'django_view_uses_model',\n metadata: {\n viewClass: className,\n modelName: querysetMatch[1],\n filePath,\n via: 'queryset',\n },\n });\n }\n\n // Extract template_name = 'app/template.html'\n const templateMatch = body.match(/template_name\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (templateMatch) {\n result.edges!.push({\n edgeType: 'django_view_template',\n metadata: {\n viewClass: className,\n templateName: templateMatch[1],\n filePath,\n },\n });\n }\n\n // Extract serializer_class (DRF)\n const serializerMatch = body.match(/serializer_class\\s*=\\s*(\\w+)/);\n if (serializerMatch) {\n result.edges!.push({\n edgeType: 'django_view_uses_model',\n metadata: {\n viewClass: className,\n serializerClass: serializerMatch[1],\n filePath,\n via: 'serializer',\n },\n });\n }\n }\n }\n\n // ============================================================\n // Form extraction (ModelForm)\n // ============================================================\n\n /**\n * Extract ModelForm Meta.model references.\n */\n private extractFormEdges(\n source: string,\n filePath: string,\n result: FileParseResult,\n ): void {\n // Match class SomethingForm(ModelForm): or class SomethingForm(forms.ModelForm):\n const formRegex = /class\\s+(\\w+)\\s*\\(\\s*(?:forms\\.)?ModelForm\\s*\\)\\s*:/g;\n let formMatch: RegExpExecArray | null;\n\n while ((formMatch = formRegex.exec(source)) !== null) {\n const formClass = formMatch[1];\n const bodyStart = formMatch.index + formMatch[0].length;\n const body = this.extractIndentedBody(source, bodyStart);\n if (!body) continue;\n\n result.frameworkRole = result.frameworkRole ?? 'form';\n\n // Find class Meta: with model = X\n const metaMatch = body.match(/class\\s+Meta\\s*:[\\s\\S]*?model\\s*=\\s*(\\w+)/);\n if (metaMatch) {\n result.edges!.push({\n edgeType: 'django_form_meta_model',\n metadata: {\n formClass,\n modelName: metaMatch[1],\n filePath,\n },\n });\n }\n }\n }\n\n // ============================================================\n // Pass 2: Resolve edges with full symbol context\n // ============================================================\n\n private resolveModelEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n const modelResults = extractDjangoModels(source, file.path);\n if (modelResults.length === 0) return;\n\n const symbols = ctx.getSymbolsByFile(file.id);\n\n for (const mr of modelResults) {\n const sourceClass = symbols.find(\n (s) => s.kind === 'class' && s.name === mr.model.name,\n );\n if (!sourceClass) continue;\n\n for (const assoc of mr.associations) {\n // Try to find the target model symbol\n const targetClass = this.findModelSymbol(ctx, assoc.targetModelName);\n if (!targetClass) continue;\n\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: sourceClass.id,\n targetNodeType: 'symbol',\n targetRefId: targetClass.id,\n edgeType: `django_${assoc.kind}`,\n metadata: {\n fieldName: assoc.options?.field,\n kind: assoc.kind,\n },\n });\n }\n }\n }\n\n private resolveAdminEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n if (!this.isAdminFile(file.path)) return;\n\n const adminEdges = extractAdminRegistrations(source, file.path);\n const symbols = ctx.getSymbolsByFile(file.id);\n\n for (const edge of adminEdges) {\n const modelName = edge.metadata?.modelName as string;\n const adminClassName = edge.metadata?.adminClass as string | undefined;\n\n const modelSymbol = this.findModelSymbol(ctx, modelName);\n if (!modelSymbol) continue;\n\n const adminSymbol = adminClassName\n ? symbols.find((s) => s.kind === 'class' && s.name === adminClassName)\n : undefined;\n\n edges.push({\n sourceNodeType: adminSymbol ? 'symbol' : 'file',\n sourceRefId: adminSymbol ? adminSymbol.id : file.id,\n targetNodeType: 'symbol',\n targetRefId: modelSymbol.id,\n edgeType: 'django_admin_registers',\n metadata: { adminClass: adminClassName },\n });\n }\n }\n\n private resolveSignalEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n const signalEdges = extractSignalConnections(source, file.path);\n if (signalEdges.length === 0) return;\n\n const symbols = ctx.getSymbolsByFile(file.id);\n\n for (const edge of signalEdges) {\n const sender = edge.metadata?.sender as string | undefined;\n if (!sender) continue;\n\n const senderSymbol = this.findModelSymbol(ctx, sender);\n if (!senderSymbol) continue;\n\n const handler = edge.metadata?.handler as string;\n const handlerSymbol = symbols.find(\n (s) => s.kind === 'function' && s.name === handler,\n );\n\n edges.push({\n sourceNodeType: handlerSymbol ? 'symbol' : 'file',\n sourceRefId: handlerSymbol ? handlerSymbol.id : file.id,\n targetNodeType: 'symbol',\n targetRefId: senderSymbol.id,\n edgeType: 'django_signal_receiver',\n metadata: {\n signal: edge.metadata?.signal,\n handler,\n },\n });\n }\n }\n\n private resolveFormEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n const formRegex = /class\\s+(\\w+)\\s*\\(\\s*(?:forms\\.)?ModelForm\\s*\\)\\s*:/g;\n let formMatch: RegExpExecArray | null;\n\n while ((formMatch = formRegex.exec(source)) !== null) {\n const formClass = formMatch[1];\n const bodyStart = formMatch.index + formMatch[0].length;\n const body = this.extractIndentedBody(source, bodyStart);\n if (!body) continue;\n\n const metaMatch = body.match(/class\\s+Meta\\s*:[\\s\\S]*?model\\s*=\\s*(\\w+)/);\n if (!metaMatch) continue;\n\n const modelName = metaMatch[1];\n const symbols = ctx.getSymbolsByFile(file.id);\n const formSymbol = symbols.find(\n (s) => s.kind === 'class' && s.name === formClass,\n );\n const modelSymbol = this.findModelSymbol(ctx, modelName);\n\n if (formSymbol && modelSymbol) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: formSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: modelSymbol.id,\n edgeType: 'django_form_meta_model',\n });\n }\n }\n }\n\n private resolveViewModelEdges(\n source: string,\n file: { id: number; path: string },\n ctx: ResolveContext,\n edges: RawEdge[],\n ): void {\n const cbvBases = [\n 'ListView', 'DetailView', 'CreateView', 'UpdateView', 'DeleteView',\n 'FormView', 'TemplateView', 'ModelViewSet', 'ReadOnlyModelViewSet',\n ];\n const basesPattern = cbvBases.map(escapeRegExp).join('|');\n const classRegex = new RegExp(\n `class\\\\s+(\\\\w+)\\\\s*\\\\((?:[\\\\w.,\\\\s]*(?:${basesPattern})[\\\\w.,\\\\s]*)\\\\)\\\\s*:`,\n 'g',\n );\n\n let classMatch: RegExpExecArray | null;\n while ((classMatch = classRegex.exec(source)) !== null) {\n const className = classMatch[1];\n const bodyStart = classMatch.index + classMatch[0].length;\n const body = this.extractIndentedBody(source, bodyStart);\n if (!body) continue;\n\n const symbols = ctx.getSymbolsByFile(file.id);\n const viewSymbol = symbols.find(\n (s) => s.kind === 'class' && s.name === className,\n );\n if (!viewSymbol) continue;\n\n // model = X\n const modelMatch = body.match(/model\\s*=\\s*(\\w+)/);\n if (modelMatch) {\n const modelSymbol = this.findModelSymbol(ctx, modelMatch[1]);\n if (modelSymbol) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: viewSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: modelSymbol.id,\n edgeType: 'django_view_uses_model',\n });\n }\n }\n\n // queryset = X.objects...\n const querysetMatch = body.match(/queryset\\s*=\\s*(\\w+)\\.objects/);\n if (querysetMatch && !modelMatch) {\n const modelSymbol = this.findModelSymbol(ctx, querysetMatch[1]);\n if (modelSymbol) {\n edges.push({\n sourceNodeType: 'symbol',\n sourceRefId: viewSymbol.id,\n targetNodeType: 'symbol',\n targetRefId: modelSymbol.id,\n edgeType: 'django_view_uses_model',\n metadata: { via: 'queryset' },\n });\n }\n }\n }\n }\n\n // ============================================================\n // Helpers\n // ============================================================\n\n private isUrlFile(filePath: string): boolean {\n return /urls\\.py$/.test(filePath);\n }\n\n private isAdminFile(filePath: string): boolean {\n return /admin\\.py$/.test(filePath) || /\\/admin\\//.test(filePath);\n }\n\n /**\n * Extract the indented body block after a class/def statement.\n */\n private extractIndentedBody(source: string, startIndex: number): string | null {\n const lines = source.substring(startIndex).split('\\n');\n const bodyLines: string[] = [];\n let baseIndent: number | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trimEnd();\n\n if (!trimmed) {\n bodyLines.push('');\n continue;\n }\n\n const indent = line.length - line.trimStart().length;\n\n if (baseIndent === null) {\n if (indent === 0 && i > 0) break;\n baseIndent = indent;\n }\n\n if (indent < baseIndent && trimmed.length > 0) break;\n\n bodyLines.push(trimmed);\n }\n\n const body = bodyLines.join('\\n').trim();\n return body || null;\n }\n\n /**\n * Find a model symbol by name across the entire project.\n * Searches by class name (unqualified).\n */\n private findModelSymbol(\n ctx: ResolveContext,\n modelName: string,\n ): { id: number; symbolId: string } | undefined {\n // Try direct FQN match (in case it's fully qualified)\n const direct = ctx.getSymbolByFqn(modelName);\n if (direct) return direct;\n\n // Search all files for a class with this name\n // This is a simplified approach; a real implementation might build a name index\n const files = ctx.getAllFiles();\n for (const file of files) {\n if (file.language !== 'python') continue;\n const symbols = ctx.getSymbolsByFile(file.id);\n const match = symbols.find(\n (s) => s.kind === 'class' && s.name === modelName,\n );\n if (match) return match;\n }\n\n return undefined;\n }\n}\n","/**\n * Django model extraction from Python source files.\n *\n * Detects:\n * - class X(models.Model): ... with field definitions\n * - ForeignKey, ManyToManyField, OneToOneField → associations\n * - Standard field types (CharField, IntegerField, etc.)\n * - Meta class options (db_table, ordering, etc.)\n */\nimport type { RawOrmModel, RawOrmAssociation } from '../../../../plugin-api/types.js';\n\nexport interface DjangoModelExtractionResult {\n model: RawOrmModel;\n associations: RawOrmAssociation[];\n}\n\n/** Relationship field types and their association kind. */\nconst RELATIONSHIP_FIELDS: Record<string, string> = {\n ForeignKey: 'foreign_key',\n ManyToManyField: 'many_to_many',\n OneToOneField: 'one_to_one',\n GenericForeignKey: 'generic_foreign_key',\n};\n\n/**\n * Extract Django model definitions from a Python source file.\n * Returns all models found in the file.\n */\nexport function extractDjangoModels(\n source: string,\n filePath: string,\n): DjangoModelExtractionResult[] {\n const results: DjangoModelExtractionResult[] = [];\n\n // Match class X(models.Model): or class X(SomeModel): with indented body\n const classRegex = /^class\\s+(\\w+)\\s*\\(\\s*([\\w.,\\s]+)\\s*\\)\\s*:/gm;\n let classMatch: RegExpExecArray | null;\n\n while ((classMatch = classRegex.exec(source)) !== null) {\n const className = classMatch[1];\n const bases = classMatch[2];\n\n // Check if this extends models.Model (or a known Django base)\n if (!isDjangoModel(bases)) continue;\n\n const classBodyStart = classMatch.index + classMatch[0].length;\n const classBody = extractClassBody(source, classBodyStart);\n if (!classBody) continue;\n\n const fields = extractFields(classBody);\n const associations = extractAssociations(classBody, className);\n const meta = extractMeta(classBody);\n\n const model: RawOrmModel = {\n name: className,\n orm: 'django',\n collectionOrTable: meta.dbTable,\n fields,\n metadata: {\n framework: 'django',\n bases,\n abstract: meta.abstract,\n ordering: meta.ordering,\n filePath,\n },\n };\n\n results.push({ model, associations });\n }\n\n return results;\n}\n\n/** Check if base classes indicate a Django model. */\nfunction isDjangoModel(bases: string): boolean {\n const baseList = bases.split(',').map((b) => b.trim());\n return baseList.some((b) =>\n b === 'models.Model' ||\n b === 'Model' ||\n b.endsWith('Model') ||\n b.endsWith('Mixin') ||\n b === 'AbstractUser' ||\n b === 'AbstractBaseUser' ||\n b === 'PermissionsMixin' ||\n b.includes('models.') ||\n // Common DRF / third-party bases\n b === 'TimeStampedModel' ||\n b === 'SoftDeletableModel',\n );\n}\n\n/**\n * Extract the indented body of a class definition.\n * Looks for contiguous lines with greater indentation than the class keyword.\n */\nfunction extractClassBody(source: string, startIndex: number): string | null {\n const lines = source.substring(startIndex).split('\\n');\n const bodyLines: string[] = [];\n let baseIndent: number | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trimEnd();\n\n // Skip empty lines\n if (!trimmed) {\n bodyLines.push('');\n continue;\n }\n\n const indent = line.length - line.trimStart().length;\n\n // First non-empty line sets the base indent\n if (baseIndent === null) {\n if (indent === 0 && i > 0) break; // Dedented immediately\n baseIndent = indent;\n }\n\n // If we've returned to the same or lesser indentation, body is done\n if (indent < baseIndent && trimmed.length > 0) break;\n\n bodyLines.push(trimmed);\n }\n\n const body = bodyLines.join('\\n').trim();\n return body || null;\n}\n\n/** Extract field definitions from a class body. */\nfunction extractFields(classBody: string): Record<string, unknown>[] {\n const fields: Record<string, unknown>[] = [];\n\n // Match: field_name = models.FieldType(...) or field_name = FieldType(...)\n const fieldRegex = /^(\\w+)\\s*=\\s*(?:models\\.)?(\\w+Field)\\s*\\(([^)]*(?:\\([^)]*\\)[^)]*)*)\\)/gm;\n let match: RegExpExecArray | null;\n\n while ((match = fieldRegex.exec(classBody)) !== null) {\n const fieldName = match[1];\n const fieldType = match[2];\n const args = match[3];\n\n const field: Record<string, unknown> = {\n name: fieldName,\n type: fieldType,\n };\n\n // Parse common field options\n if (/max_length\\s*=\\s*(\\d+)/.test(args)) {\n field.maxLength = parseInt(args.match(/max_length\\s*=\\s*(\\d+)/)![1], 10);\n }\n if (/null\\s*=\\s*True/.test(args)) field.nullable = true;\n if (/blank\\s*=\\s*True/.test(args)) field.blank = true;\n if (/unique\\s*=\\s*True/.test(args)) field.unique = true;\n if (/primary_key\\s*=\\s*True/.test(args)) field.primaryKey = true;\n if (/db_index\\s*=\\s*True/.test(args)) field.index = true;\n\n const defaultMatch = args.match(/default\\s*=\\s*([^,)]+)/);\n if (defaultMatch) field.default = defaultMatch[1].trim();\n\n // For relationship fields, extract the target model\n if (fieldType in RELATIONSHIP_FIELDS) {\n const target = extractRelationshipTarget(args);\n if (target) field.relatedModel = target;\n\n const relatedName = args.match(/related_name\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (relatedName) field.relatedName = relatedName[1];\n\n const onDelete = args.match(/on_delete\\s*=\\s*(?:models\\.)?(\\w+)/);\n if (onDelete) field.onDelete = onDelete[1];\n }\n\n fields.push(field);\n }\n\n return fields;\n}\n\n/** Extract the target model name from a relationship field's arguments. */\nfunction extractRelationshipTarget(args: string): string | null {\n // First positional argument: 'AppName.ModelName', 'ModelName', ModelName, 'self'\n const stringTarget = args.match(/^\\s*['\"]([^'\"]+)['\"]/);\n if (stringTarget) return stringTarget[1];\n\n // Direct reference: ForeignKey(User, ...) or ForeignKey(User)\n const directTarget = args.match(/^\\s*(\\w+)/);\n if (directTarget && directTarget[1] !== 'to' && directTarget[1] !== 'self') {\n return directTarget[1];\n }\n\n // to='ModelName' keyword\n const toKw = args.match(/to\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (toKw) return toKw[1];\n\n // to=ModelName\n const toRef = args.match(/to\\s*=\\s*(\\w+)/);\n if (toRef) return toRef[1];\n\n // 'self' reference\n if (/^\\s*['\"]self['\"]/.test(args) || /^\\s*self\\b/.test(args)) return 'self';\n\n return null;\n}\n\n/** Extract associations (relationship fields) from a class body. */\nfunction extractAssociations(\n classBody: string,\n sourceModelName: string,\n): RawOrmAssociation[] {\n const associations: RawOrmAssociation[] = [];\n const lines = classBody.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n for (const [fieldType, kind] of Object.entries(RELATIONSHIP_FIELDS)) {\n // Match: name = models.ForeignKey(...) or name = ForeignKey(...)\n const regex = new RegExp(\n `^(\\\\w+)\\\\s*=\\\\s*(?:models\\\\.)?${fieldType}\\\\s*\\\\((.*)\\\\)`,\n );\n const match = line.match(regex);\n if (!match) continue;\n\n const args = match[2];\n const target = extractRelationshipTarget(args);\n if (!target || target === 'self') continue;\n\n // Normalize 'app_label.ModelName' to just 'ModelName'\n const targetModel = target.includes('.') ? target.split('.').pop()! : target;\n\n associations.push({\n sourceModelName,\n targetModelName: targetModel,\n kind,\n options: { fieldName: match[1] },\n line: i + 1,\n });\n }\n }\n\n return associations;\n}\n\n/** Extract Meta class options. */\nfunction extractMeta(classBody: string): {\n dbTable?: string;\n abstract?: boolean;\n ordering?: string[];\n} {\n const meta: { dbTable?: string; abstract?: boolean; ordering?: string[] } = {};\n\n // Match class Meta: block\n const metaMatch = classBody.match(/class\\s+Meta\\s*:\\s*\\n([\\s\\S]*?)(?=\\n\\s*(?:class\\s|def\\s|\\w+\\s*=)|$)/);\n if (!metaMatch) return meta;\n\n const metaBody = metaMatch[1];\n\n const dbTable = metaBody.match(/db_table\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (dbTable) meta.dbTable = dbTable[1];\n\n if (/abstract\\s*=\\s*True/.test(metaBody)) meta.abstract = true;\n\n const ordering = metaBody.match(/ordering\\s*=\\s*\\[([^\\]]*)\\]/);\n if (ordering) {\n const items: string[] = [];\n const regex = /['\"]([^'\"]+)['\"]/g;\n let m: RegExpExecArray | null;\n while ((m = regex.exec(ordering[1])) !== null) {\n items.push(m[1]);\n }\n meta.ordering = items;\n }\n\n return meta;\n}\n","/**\n * Django URL pattern extraction from urls.py files.\n *\n * Detects:\n * - path('route/', view, name='name') → RawRoute\n * - re_path(r'^pattern/$', view) → RawRoute\n * - url(r'^pattern/$', view) → RawRoute (Django 1.x compat)\n * - include('app.urls') → django_includes_urls edge\n * - Router-based DRF patterns: router.register('prefix', ViewSet)\n */\nimport type { RawRoute, RawEdge } from '../../../../plugin-api/types.js';\n\nexport interface UrlExtractionResult {\n routes: RawRoute[];\n edges: RawEdge[];\n warnings: string[];\n}\n\n/**\n * Extract URL patterns from a Django urls.py source file.\n */\nexport function extractUrlPatterns(\n source: string,\n filePath: string,\n): UrlExtractionResult {\n const routes: RawRoute[] = [];\n const edges: RawEdge[] = [];\n const warnings: string[] = [];\n\n // Extract path() calls\n extractPathCalls(source, routes, edges);\n\n // Extract re_path() calls\n extractRePathCalls(source, routes);\n\n // Extract legacy url() calls (Django 1.x)\n extractLegacyUrlCalls(source, routes, edges);\n\n // Extract DRF router registrations\n extractDrfRouterPatterns(source, routes);\n\n return { routes, edges, warnings };\n}\n\n/**\n * Extract path('route/', view, name='name') patterns.\n * Also detects path('api/', include('app.urls')).\n */\nfunction extractPathCalls(\n source: string,\n routes: RawRoute[],\n edges: RawEdge[],\n): void {\n // path('uri', view_function_or_class, name='...')\n // path('uri', include('module.urls'))\n // Handler may contain nested parens like .as_view(), so allow them\n const pathRegex = /path\\s*\\(\\s*['\"]([^'\"]*)['\"]\\s*,\\s*([^,]+(?:\\([^)]*\\))?[^,]*)(?:\\s*,\\s*([^)]*))?\\s*\\)/g;\n let match: RegExpExecArray | null;\n\n while ((match = pathRegex.exec(source)) !== null) {\n const uri = match[1];\n const handler = match[2].trim();\n const extraArgs = match[3] || '';\n\n // Check if this is an include()\n const includeMatch = handler.match(/include\\s*\\(\\s*['\"]([^'\"]+)['\"]/);\n if (includeMatch) {\n edges.push({\n edgeType: 'django_includes_urls',\n metadata: {\n sourceFile: source,\n prefix: uri,\n includedModule: includeMatch[1],\n },\n });\n continue;\n }\n\n // Check for include() with namespace\n const includeNsMatch = handler.match(/include\\s*\\(\\s*\\(\\s*['\"]([^'\"]+)['\"].*?namespace\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (includeNsMatch) {\n edges.push({\n edgeType: 'django_includes_urls',\n metadata: {\n prefix: uri,\n includedModule: includeNsMatch[1],\n namespace: includeNsMatch[2],\n },\n });\n continue;\n }\n\n // Regular view route\n const name = extractRouteName(extraArgs);\n const viewName = normalizeViewRef(handler);\n\n routes.push({\n method: 'GET', // Django path() handles all methods; default to GET\n uri: `/${uri}`.replace(/\\/+/g, '/'),\n name: name ?? undefined,\n controllerSymbolId: viewName,\n });\n }\n}\n\n/**\n * Extract re_path(r'^pattern/$', view) patterns.\n */\nfunction extractRePathCalls(\n source: string,\n routes: RawRoute[],\n): void {\n const rePathRegex = /re_path\\s*\\(\\s*r?['\"]([^'\"]+)['\"]\\s*,\\s*([^,)]+)(?:\\s*,\\s*([^)]*))?\\s*\\)/g;\n let match: RegExpExecArray | null;\n\n while ((match = rePathRegex.exec(source)) !== null) {\n const pattern = match[1];\n const handler = match[2].trim();\n const extraArgs = match[3] || '';\n\n // Skip include() patterns\n if (handler.includes('include(')) continue;\n\n const name = extractRouteName(extraArgs);\n const viewName = normalizeViewRef(handler);\n const uri = regexPatternToUri(pattern);\n\n routes.push({\n method: 'GET',\n uri,\n name: name ?? undefined,\n controllerSymbolId: viewName,\n });\n }\n}\n\n/**\n * Extract legacy url(r'^pattern/$', view) patterns (Django 1.x).\n */\nfunction extractLegacyUrlCalls(\n source: string,\n routes: RawRoute[],\n edges: RawEdge[],\n): void {\n const urlRegex = /\\burl\\s*\\(\\s*r?['\"]([^'\"]+)['\"]\\s*,\\s*([^,)]+)(?:\\s*,\\s*([^)]*))?\\s*\\)/g;\n let match: RegExpExecArray | null;\n\n while ((match = urlRegex.exec(source)) !== null) {\n const pattern = match[1];\n const handler = match[2].trim();\n const extraArgs = match[3] || '';\n\n // Check for include()\n const includeMatch = handler.match(/include\\s*\\(\\s*['\"]([^'\"]+)['\"]/);\n if (includeMatch) {\n edges.push({\n edgeType: 'django_includes_urls',\n metadata: {\n prefix: regexPatternToUri(pattern),\n includedModule: includeMatch[1],\n },\n });\n continue;\n }\n\n const name = extractRouteName(extraArgs);\n const viewName = normalizeViewRef(handler);\n const uri = regexPatternToUri(pattern);\n\n routes.push({\n method: 'GET',\n uri,\n name: name ?? undefined,\n controllerSymbolId: viewName,\n });\n }\n}\n\n/**\n * Extract DRF router registrations:\n * router.register(r'users', UserViewSet, basename='user')\n */\nfunction extractDrfRouterPatterns(\n source: string,\n routes: RawRoute[],\n): void {\n const routerRegex = /(\\w+)\\.register\\s*\\(\\s*r?['\"]([^'\"]+)['\"]\\s*,\\s*(\\w+)(?:\\s*,\\s*([^)]*))?\\s*\\)/g;\n let match: RegExpExecArray | null;\n\n while ((match = routerRegex.exec(source)) !== null) {\n const prefix = match[2];\n const viewSetName = match[3];\n const extraArgs = match[4] || '';\n\n const basenameMatch = extraArgs.match(/basename\\s*=\\s*['\"]([^'\"]+)['\"]/);\n const basename = basenameMatch?.[1] ?? prefix;\n\n // DRF ViewSet generates list/create/retrieve/update/destroy\n const viewSetRoutes: Array<{ method: string; suffix: string; action: string }> = [\n { method: 'GET', suffix: '/', action: 'list' },\n { method: 'POST', suffix: '/', action: 'create' },\n { method: 'GET', suffix: '/{pk}/', action: 'retrieve' },\n { method: 'PUT', suffix: '/{pk}/', action: 'update' },\n { method: 'PATCH', suffix: '/{pk}/', action: 'partial_update' },\n { method: 'DELETE', suffix: '/{pk}/', action: 'destroy' },\n ];\n\n for (const r of viewSetRoutes) {\n routes.push({\n method: r.method,\n uri: `/${prefix}${r.suffix}`.replace(/\\/+/g, '/'),\n name: `${basename}-${r.action}`,\n controllerSymbolId: `${viewSetName}.${r.action}`,\n });\n }\n }\n}\n\n/** Extract name='...' from extra arguments. */\nfunction extractRouteName(extraArgs: string): string | null {\n const nameMatch = extraArgs.match(/name\\s*=\\s*['\"]([^'\"]+)['\"]/);\n return nameMatch ? nameMatch[1] : null;\n}\n\n/** Normalize a view reference to a clean handler name. */\nfunction normalizeViewRef(handler: string): string {\n // views.user_list → views.user_list\n // UserView.as_view() → UserView\n let ref = handler.trim();\n ref = ref.replace(/\\.as_view\\s*\\(\\s*\\)/, '');\n return ref;\n}\n\n/**\n * Convert a Django URL regex pattern to a URI-like string.\n * e.g., r'^users/(?P<pk>\\d+)/$' → /users/{pk}/\n */\nfunction regexPatternToUri(pattern: string): string {\n let uri = pattern;\n // Remove regex anchors\n uri = uri.replace(/^\\^/, '').replace(/\\$$/, '');\n // Convert named groups: (?P<name>...) → {name}\n uri = uri.replace(/\\(\\?P<(\\w+)>[^)]+\\)/g, '{$1}');\n // Convert unnamed groups\n uri = uri.replace(/\\([^)]+\\)/g, '{param}');\n // Ensure leading slash\n if (!uri.startsWith('/')) uri = `/${uri}`;\n return uri;\n}\n","/**\n * Django signal extraction from Python source files.\n *\n * Detects:\n * - @receiver(post_save, sender=User) decorator pattern\n * - signal.connect(handler, sender=User) imperative pattern\n * - Common Django signals: pre_save, post_save, pre_delete, post_delete,\n * m2m_changed, pre_init, post_init, pre_migrate, post_migrate, request_started, etc.\n */\nimport type { RawEdge } from '../../../../plugin-api/types.js';\n\nexport interface SignalConnection {\n signal: string;\n handler: string;\n sender?: string;\n line: number;\n}\n\n/**\n * Extract signal connections from Django source code.\n * Returns edges of type django_signal_receiver.\n */\nexport function extractSignalConnections(\n source: string,\n filePath: string,\n): RawEdge[] {\n const edges: RawEdge[] = [];\n const connections = [\n ...extractReceiverDecorators(source),\n ...extractConnectCalls(source),\n ];\n\n for (const conn of connections) {\n edges.push({\n edgeType: 'django_signal_receiver',\n metadata: {\n signal: conn.signal,\n handler: conn.handler,\n sender: conn.sender,\n filePath,\n line: conn.line,\n },\n });\n }\n\n return edges;\n}\n\n/**\n * Extract @receiver(signal, sender=Model) patterns.\n *\n * Handles:\n * - @receiver(post_save, sender=User)\n * - @receiver(post_save, sender='myapp.User')\n * - @receiver([post_save, post_delete], sender=User)\n */\nfunction extractReceiverDecorators(source: string): SignalConnection[] {\n const connections: SignalConnection[] = [];\n const lines = source.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // Match @receiver(...) decorator\n const decoratorMatch = line.match(\n /^@receiver\\s*\\(\\s*(.+)\\s*\\)\\s*$/,\n );\n if (!decoratorMatch) continue;\n\n const argsStr = decoratorMatch[1];\n\n // Find the function name on the next non-decorator, non-empty line\n let handler = '';\n for (let j = i + 1; j < lines.length && j < i + 5; j++) {\n const nextLine = lines[j].trim();\n if (!nextLine || nextLine.startsWith('@')) continue;\n const funcMatch = nextLine.match(/^(?:async\\s+)?def\\s+(\\w+)/);\n if (funcMatch) {\n handler = funcMatch[1];\n }\n break;\n }\n\n if (!handler) continue;\n\n // Parse signal(s) and sender\n const sender = extractSender(argsStr);\n const signals = extractSignalNames(argsStr);\n\n for (const signal of signals) {\n connections.push({\n signal,\n handler,\n sender: sender ?? undefined,\n line: i + 1,\n });\n }\n }\n\n return connections;\n}\n\n/**\n * Extract signal.connect(handler, sender=Model) patterns.\n *\n * Handles:\n * - post_save.connect(my_handler, sender=User)\n * - signals.post_save.connect(handler, sender=User)\n */\nfunction extractConnectCalls(source: string): SignalConnection[] {\n const connections: SignalConnection[] = [];\n const lines = source.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n const connectMatch = line.match(\n /(?:(?:signals?\\.)?(\\w+))\\.connect\\s*\\(\\s*(\\w+)(?:\\s*,\\s*(.+))?\\s*\\)/,\n );\n if (!connectMatch) continue;\n\n const signal = connectMatch[1];\n const handler = connectMatch[2];\n const extraArgs = connectMatch[3] || '';\n\n const sender = extractSender(extraArgs);\n\n connections.push({\n signal,\n handler,\n sender: sender ?? undefined,\n line: i + 1,\n });\n }\n\n return connections;\n}\n\n/** Extract sender= value from argument string. */\nfunction extractSender(argsStr: string): string | null {\n // sender=ModelName or sender='app.ModelName'\n const senderMatch = argsStr.match(/sender\\s*=\\s*(?:['\"]([^'\"]+)['\"]|(\\w+))/);\n if (!senderMatch) return null;\n const raw = senderMatch[1] ?? senderMatch[2];\n // Normalize 'app.Model' to 'Model'\n return raw.includes('.') ? raw.split('.').pop()! : raw;\n}\n\n/** Extract signal name(s) from the first argument. */\nfunction extractSignalNames(argsStr: string): string[] {\n // Remove sender=... and anything after it for parsing the signal part\n const signalPart = argsStr.replace(/,?\\s*sender\\s*=\\s*(?:['\"][^'\"]+['\"]|\\w+)/, '').trim();\n\n // List of signals: [post_save, post_delete]\n const listMatch = signalPart.match(/^\\[([^\\]]+)\\]/);\n if (listMatch) {\n return listMatch[1]\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n .map(normalizeSignalName);\n }\n\n // Single signal: post_save or signals.post_save\n const singleMatch = signalPart.match(/^(?:signals?\\.)?(\\w+)/);\n if (singleMatch) return [normalizeSignalName(singleMatch[0])];\n\n return [];\n}\n\n/** Normalize signal name by stripping 'signals.' prefix. */\nfunction normalizeSignalName(name: string): string {\n return name.replace(/^signals?\\./, '').trim();\n}\n","/**\n * Django admin extraction from Python source files.\n *\n * Detects:\n * - @admin.register(Model) decorator\n * - @admin.register(Model1, Model2) multi-model registration\n * - admin.site.register(Model, AdminClass)\n * - admin.site.register(Model)\n * - admin.site.register([Model1, Model2], AdminClass)\n *\n * Produces edges of type django_admin_registers.\n */\nimport type { RawEdge } from '../../../../plugin-api/types.js';\n\nexport interface AdminRegistration {\n modelName: string;\n adminClass?: string;\n line: number;\n}\n\n/**\n * Extract admin registrations from Django source code.\n * Returns edges of type django_admin_registers.\n */\nexport function extractAdminRegistrations(\n source: string,\n filePath: string,\n): RawEdge[] {\n const edges: RawEdge[] = [];\n const registrations = [\n ...extractDecoratorRegistrations(source),\n ...extractSiteRegistrations(source),\n ];\n\n for (const reg of registrations) {\n edges.push({\n edgeType: 'django_admin_registers',\n metadata: {\n modelName: reg.modelName,\n adminClass: reg.adminClass,\n filePath,\n line: reg.line,\n },\n });\n }\n\n return edges;\n}\n\n/**\n * Extract @admin.register(Model) decorator patterns.\n *\n * Matches:\n * - @admin.register(User)\n * - @admin.register(User, Group)\n * - @admin.register(User, site=custom_site)\n */\nfunction extractDecoratorRegistrations(source: string): AdminRegistration[] {\n const registrations: AdminRegistration[] = [];\n const lines = source.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n const decoratorMatch = line.match(\n /^@admin\\.register\\s*\\(\\s*([^)]+)\\s*\\)/,\n );\n if (!decoratorMatch) continue;\n\n const argsStr = decoratorMatch[1];\n\n // Find the admin class on the next non-decorator, non-empty line\n let adminClass: string | undefined;\n for (let j = i + 1; j < lines.length && j < i + 5; j++) {\n const nextLine = lines[j].trim();\n if (!nextLine || nextLine.startsWith('@')) continue;\n const classMatch = nextLine.match(/^class\\s+(\\w+)/);\n if (classMatch) {\n adminClass = classMatch[1];\n }\n break;\n }\n\n // Parse model names (strip site=... keyword args)\n const models = argsStr\n .replace(/\\bsite\\s*=\\s*\\w+/, '')\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0 && !s.includes('='));\n\n for (const modelName of models) {\n registrations.push({\n modelName,\n adminClass,\n line: i + 1,\n });\n }\n }\n\n return registrations;\n}\n\n/**\n * Extract admin.site.register(Model, AdminClass) patterns.\n *\n * Matches:\n * - admin.site.register(User, UserAdmin)\n * - admin.site.register(User)\n * - admin.site.register([User, Group], UserAdmin)\n */\nfunction extractSiteRegistrations(source: string): AdminRegistration[] {\n const registrations: AdminRegistration[] = [];\n const lines = source.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // admin.site.register(Model, AdminClass) or admin.site.register(Model)\n const singleMatch = line.match(\n /admin\\.site\\.register\\s*\\(\\s*(\\w+)(?:\\s*,\\s*(\\w+))?\\s*\\)/,\n );\n if (singleMatch) {\n registrations.push({\n modelName: singleMatch[1],\n adminClass: singleMatch[2],\n line: i + 1,\n });\n continue;\n }\n\n // admin.site.register([Model1, Model2], AdminClass)\n const listMatch = line.match(\n /admin\\.site\\.register\\s*\\(\\s*\\[([^\\]]+)\\](?:\\s*,\\s*(\\w+))?\\s*\\)/,\n );\n if (listMatch) {\n const models = listMatch[1]\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n const adminClass = listMatch[2];\n\n for (const modelName of models) {\n registrations.push({\n modelName,\n adminClass,\n line: i + 1,\n });\n }\n }\n }\n\n return registrations;\n}\n","/**\n * ReactPlugin — Standalone React (16-19) framework plugin.\n *\n * Detects React projects that are NOT Next.js or React Native (those have\n * dedicated plugins) and extracts:\n * - JSX child component rendering (react_renders)\n * - Context creation and Context.Provider usage (react_context_provides)\n * - useContext() / use() consumption (react_context_consumes)\n * - React.lazy() dynamic imports (react_lazy_loads)\n * - Custom hook usage (react_custom_hook_uses)\n * - 'use client' / 'use server' directives — React 19 (react_use_client / react_use_server)\n *\n * Uses tree-sitter-typescript for AST-based extraction of JSX/TSX.\n */\nimport { createRequire } from 'node:module';\nimport { ok, err } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawComponent,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\nimport { parseError } from '../../../../errors.js';\n\nconst require = createRequire(import.meta.url);\nconst Parser = require('tree-sitter');\nconst TsGrammar = require('tree-sitter-typescript');\n\n// tree-sitter types (CJS interop)\ntype TSNode = {\n type: string;\n text: string;\n startIndex: number;\n endIndex: number;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n namedChildCount: number;\n childCount: number;\n namedChildren: TSNode[];\n namedChild(index: number): TSNode | null;\n child(index: number): TSNode | null;\n childForFieldName(name: string): TSNode | null;\n parent: TSNode | null;\n isNamed: boolean;\n hasError: boolean;\n};\n\nlet tsParser: InstanceType<typeof Parser> | null = null;\nlet tsxParser: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(tsx: boolean): InstanceType<typeof Parser> {\n if (tsx) {\n if (!tsxParser) {\n tsxParser = new Parser();\n tsxParser!.setLanguage(TsGrammar.tsx);\n }\n return tsxParser!;\n }\n if (!tsParser) {\n tsParser = new Parser();\n tsParser!.setLanguage(TsGrammar.typescript);\n }\n return tsParser!;\n}\n\n// ============================================================\n// Built-in hooks — we skip these when detecting custom hook usage\n// ============================================================\n\nconst BUILTIN_HOOKS = new Set([\n 'useState',\n 'useEffect',\n 'useRef',\n 'useMemo',\n 'useCallback',\n 'useReducer',\n 'useContext',\n 'useLayoutEffect',\n 'useImperativeHandle',\n 'useDebugValue',\n 'useId',\n 'useTransition',\n 'useDeferredValue',\n 'useSyncExternalStore',\n 'useInsertionEffect',\n 'useOptimistic',\n 'useFormStatus',\n 'useActionState',\n]);\n\n// ============================================================\n// AST helpers\n// ============================================================\n\n/** Walk all descendants depth-first. */\nfunction* walk(node: TSNode): Generator<TSNode> {\n yield node;\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n if (child) yield* walk(child);\n }\n}\n\n/** Get the text of a call_expression's function node (handles `foo`, `Mod.foo`, `React.lazy`). */\nfunction callName(node: TSNode): string {\n const fn = node.childForFieldName('function');\n return fn?.text ?? '';\n}\n\n/** Get the first argument node of a call_expression. */\nfunction firstArg(node: TSNode): TSNode | null {\n const args = node.childForFieldName('arguments');\n if (!args) return null;\n for (let i = 0; i < args.namedChildCount; i++) {\n const child = args.namedChild(i);\n if (child && child.isNamed) return child;\n }\n return null;\n}\n\n/** Get the tag name of a JSX element (opening tag or self-closing). */\nfunction jsxTagName(node: TSNode): string | null {\n if (node.type === 'jsx_self_closing_element') {\n const nameNode = node.childForFieldName('name');\n return nameNode?.text ?? null;\n }\n if (node.type === 'jsx_element') {\n const openTag = node.childForFieldName('open_tag');\n if (openTag) {\n const nameNode = openTag.childForFieldName('name');\n return nameNode?.text ?? null;\n }\n }\n return null;\n}\n\n/** Determine if a JSX tag name is a PascalCase component (not an HTML built-in). */\nfunction isPascalCase(name: string): boolean {\n // Handle dotted names like `ThemeContext.Provider` — first segment must be uppercase\n const first = name.split('.')[0];\n return /^[A-Z]/.test(first);\n}\n\n// ============================================================\n// Plugin\n// ============================================================\n\nexport class ReactPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'react',\n version: '1.0.0',\n priority: 20,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n const deps = {\n ...(ctx.packageJson?.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson?.devDependencies as Record<string, string> | undefined),\n };\n // React standalone: has react, but NOT next or react-native (those have their own plugins)\n return 'react' in deps && !('next' in deps) && !('react-native' in deps);\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'react_renders', category: 'react', description: 'Parent component renders child via JSX' },\n { name: 'react_context_provides', category: 'react', description: 'Context.Provider usage' },\n { name: 'react_context_consumes', category: 'react', description: 'useContext() or use() call' },\n { name: 'react_lazy_loads', category: 'react', description: 'React.lazy(() => import(\"./X\"))' },\n { name: 'react_custom_hook_uses', category: 'react', description: 'Component calls a custom hook' },\n { name: 'react_use_client', category: 'react', description: \"'use client' directive (React 19)\" },\n { name: 'react_use_server', category: 'react', description: \"'use server' directive (React 19)\" },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (!['typescript', 'typescriptreact', 'javascript', 'javascriptreact'].includes(language)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n if (!source.trim()) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n edges: [],\n components: [],\n };\n\n // 1. 'use client' / 'use server' directives (regex — first string statement)\n this.extractDirectives(source, result);\n\n // 2-7. AST-based extraction\n try {\n const useTsx = /\\.(tsx|jsx)$/.test(filePath);\n const parser = getParser(useTsx);\n const tree = parser.parse(source);\n const root: TSNode = tree.rootNode;\n\n for (const node of walk(root)) {\n switch (node.type) {\n case 'call_expression':\n this.visitCallExpression(node, result);\n break;\n case 'jsx_self_closing_element':\n case 'jsx_element':\n this.visitJsxElement(node, result);\n break;\n }\n }\n } catch (e) {\n return err(parseError(filePath, `tree-sitter parse failed: ${e}`));\n }\n\n return ok(result);\n }\n\n resolveEdges(_ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n // Cross-file resolution (e.g., linking context providers to consumers by\n // matching context names) could be added here in the future.\n return ok([]);\n }\n\n // ============================================================\n // Private extraction methods\n // ============================================================\n\n /** 1. 'use client' / 'use server' directives */\n private extractDirectives(source: string, result: FileParseResult): void {\n // Match the first string literal statement at file start (after comments/whitespace)\n const match = source.match(/^(?:\\s|\\/\\/[^\\n]*\\n|\\/\\*[\\s\\S]*?\\*\\/)*['\"]use (client|server)['\"]/);\n if (match) {\n const directive = match[1] as 'client' | 'server';\n if (directive === 'client') {\n result.frameworkRole = 'client-component';\n result.edges!.push({\n edgeType: 'react_use_client',\n metadata: { directive: 'use client' },\n });\n } else {\n result.frameworkRole = 'server-action';\n result.edges!.push({\n edgeType: 'react_use_server',\n metadata: { directive: 'use server' },\n });\n }\n }\n }\n\n /** Visit call_expression nodes for context creation, useContext, React.lazy, custom hooks. */\n private visitCallExpression(node: TSNode, result: FileParseResult): void {\n const name = callName(node);\n\n // 2. Context creation: createContext() or React.createContext()\n if (name === 'createContext' || name === 'React.createContext') {\n // Try to get the variable name: const ThemeContext = createContext(...)\n const parent = node.parent;\n let contextName = 'UnnamedContext';\n if (parent?.type === 'variable_declarator') {\n const nameNode = parent.childForFieldName('name');\n if (nameNode) contextName = nameNode.text;\n }\n\n result.components!.push({\n name: contextName,\n kind: 'context',\n framework: 'react',\n } as RawComponent);\n return;\n }\n\n // 4. useContext(ThemeContext) or use(ThemeContext) — React 19\n if (name === 'useContext' || name === 'use') {\n const arg = firstArg(node);\n if (arg && arg.type === 'identifier') {\n result.edges!.push({\n edgeType: 'react_context_consumes',\n metadata: { contextName: arg.text },\n });\n }\n return;\n }\n\n // 5. React.lazy(() => import('./Foo')) or lazy(() => import('./Foo'))\n if (name === 'React.lazy' || name === 'lazy') {\n const arg = firstArg(node);\n const importPath = this.extractLazyImportPath(arg);\n if (importPath) {\n result.edges!.push({\n edgeType: 'react_lazy_loads',\n metadata: { importPath },\n });\n }\n return;\n }\n\n // 6. Custom hook usage: useFoo() where useFoo starts with 'use' + uppercase\n if (/^use[A-Z]/.test(name) && !BUILTIN_HOOKS.has(name)) {\n result.edges!.push({\n edgeType: 'react_custom_hook_uses',\n metadata: { hookName: name },\n });\n }\n }\n\n /** Visit JSX elements for child component rendering and Context.Provider. */\n private visitJsxElement(node: TSNode, result: FileParseResult): void {\n const tag = jsxTagName(node);\n if (!tag) return;\n\n // 3. Context.Provider: <ThemeContext.Provider>\n if (tag.endsWith('.Provider') && isPascalCase(tag)) {\n const contextName = tag.replace(/\\.Provider$/, '');\n result.edges!.push({\n edgeType: 'react_context_provides',\n metadata: { contextName },\n });\n return;\n }\n\n // 7. JSX child component rendering: PascalCase tag names\n if (isPascalCase(tag)) {\n // Skip dotted names that aren't providers (e.g. Foo.Bar is still a component render)\n result.edges!.push({\n edgeType: 'react_renders',\n metadata: { componentName: tag },\n });\n }\n }\n\n /** Extract the dynamic import path from a lazy() arrow function body. */\n private extractLazyImportPath(arg: TSNode | null): string | null {\n if (!arg) return null;\n\n // Walk into the arrow function body to find import('...')\n for (const child of walk(arg)) {\n if (child.type === 'call_expression') {\n const fn = child.childForFieldName('function');\n if (fn?.type === 'import') {\n const importArg = firstArg(child);\n if (importArg && (importArg.type === 'string' || importArg.type === 'template_string')) {\n // Strip quotes\n return importArg.text.replace(/^['\"`]|['\"`]$/g, '');\n }\n }\n }\n }\n return null;\n }\n}\n","/**\n * TrpcPlugin — detects tRPC projects and extracts router definitions,\n * procedures (query, mutation, subscription).\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\n// Match procedure name + type. Uses [\\s\\S]{0,500}? to bridge .input(...) chains\n// with nested parens that [^)]* can't handle.\nconst PROCEDURE_RE =\n /(\\w+)\\s*:\\s*\\w*[Pp]rocedure[\\s\\S]{0,500}?\\.(query|mutation|subscription)\\s*\\(/g;\n\nconst ROUTER_RE =\n /(?:t\\.router|router)\\s*\\(\\s*\\{/g;\n\nexport interface TrpcProcedure {\n name: string;\n type: 'query' | 'mutation' | 'subscription';\n}\n\n/** Extract tRPC procedure definitions from source code. */\nexport function extractTrpcProcedures(source: string): TrpcProcedure[] {\n const procedures: TrpcProcedure[] = [];\n const re = new RegExp(PROCEDURE_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n procedures.push({\n name: match[1],\n type: match[2] as TrpcProcedure['type'],\n });\n }\n return procedures;\n}\n\nexport class TrpcPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'trpc',\n version: '1.0.0',\n priority: 25,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if ('@trpc/server' in deps) return true;\n }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n return '@trpc/server' in deps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'trpc_procedure', category: 'trpc', description: 'Procedure defined in router' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (!['typescript', 'javascript'].includes(language)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = { status: 'ok', symbols: [], routes: [], edges: [] };\n\n // Check for router definitions\n const hasRouter = new RegExp(ROUTER_RE.source, 'g').test(source);\n\n const procedures = extractTrpcProcedures(source);\n if (procedures.length > 0) {\n result.frameworkRole = hasRouter ? 'trpc_router' : 'trpc_procedure';\n for (const proc of procedures) {\n result.routes!.push({\n method: proc.type.toUpperCase() as string,\n uri: proc.name,\n });\n }\n } else if (hasRouter) {\n result.frameworkRole = 'trpc_router';\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n return ok(edges);\n }\n}\n","/**\n * FastifyPlugin — detects Fastify projects and extracts route handlers,\n * lifecycle hooks, and plugin registrations.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\n// fastify.get('/path', handler) or fastify.post('/path', opts, handler)\nconst SHORTHAND_ROUTE_RE =\n /(?:fastify|app|server|instance)\\s*\\.\\s*(get|post|put|delete|patch|head|options)\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n\n// fastify.route({ method: 'GET', url: '/path', ... })\nconst ROUTE_OBJECT_RE =\n /\\.route\\s*\\(\\s*\\{[^}]*?method\\s*:\\s*['\"`]([^'\"`]+)['\"`][^}]*?url\\s*:\\s*['\"`]([^'\"`]+)['\"`]/g;\n\n// fastify.addHook('onRequest', ...)\nconst HOOK_RE =\n /\\.addHook\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n\n// fastify.register(pluginName, ...)\nconst REGISTER_RE =\n /\\.register\\s*\\(\\s*([A-Za-z][\\w.]*)/g;\n\nexport interface FastifyRoute {\n method: string;\n path: string;\n}\n\n/** Extract route definitions from Fastify source code. */\nexport function extractFastifyRoutes(source: string): FastifyRoute[] {\n const routes: FastifyRoute[] = [];\n\n // Shorthand methods: fastify.get('/path', ...)\n const shortRe = new RegExp(SHORTHAND_ROUTE_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = shortRe.exec(source)) !== null) {\n routes.push({\n method: match[1].toUpperCase(),\n path: match[2],\n });\n }\n\n // Route object: fastify.route({ method: 'GET', url: '/path' })\n const objRe = new RegExp(ROUTE_OBJECT_RE.source, 'g');\n while ((match = objRe.exec(source)) !== null) {\n routes.push({\n method: match[1].toUpperCase(),\n path: match[2],\n });\n }\n\n return routes;\n}\n\n/** Extract lifecycle hook names from Fastify source code. */\nexport function extractFastifyHooks(source: string): string[] {\n const hooks: string[] = [];\n const re = new RegExp(HOOK_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n hooks.push(match[1]);\n }\n return hooks;\n}\n\n/** Extract plugin registration names from Fastify source code. */\nexport function extractFastifyPlugins(source: string): string[] {\n const plugins: string[] = [];\n const re = new RegExp(REGISTER_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n plugins.push(match[1]);\n }\n return plugins;\n}\n\nexport class FastifyPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'fastify',\n version: '1.0.0',\n priority: 25,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if ('fastify' in deps) return true;\n }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n return 'fastify' in deps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'fastify_route', category: 'fastify', description: 'Route handler' },\n { name: 'fastify_hook', category: 'fastify', description: 'Lifecycle hook' },\n { name: 'fastify_plugin', category: 'fastify', description: 'Plugin registration' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (!['typescript', 'javascript'].includes(language)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = { status: 'ok', symbols: [], routes: [], edges: [] };\n\n const routes = extractFastifyRoutes(source);\n if (routes.length > 0) {\n result.frameworkRole = 'fastify_route';\n for (const route of routes) {\n result.routes!.push({\n method: route.method,\n uri: route.path,\n });\n }\n }\n\n const hooks = extractFastifyHooks(source);\n if (hooks.length > 0) {\n result.frameworkRole = result.frameworkRole ?? 'fastify_hook';\n }\n\n const plugins = extractFastifyPlugins(source);\n if (plugins.length > 0) {\n result.frameworkRole = result.frameworkRole ?? 'fastify_plugin';\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n return ok(edges);\n }\n}\n","/**\n * HonoPlugin — detects Hono projects and extracts route handlers,\n * middleware usage, and route groups.\n *\n * Hono is a modern, ultrafast web framework for the Edge\n * (Cloudflare Workers, Deno, Bun, Node.js).\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\n// app.get('/path', handler), app.post(...), etc.\nconst ROUTE_RE =\n /(?:app|router|hono)\\s*\\.\\s*(get|post|put|delete|patch|head|options|all)\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n\n// app.on('GET', '/path', handler) or app.on('POST', '/path', handler)\nconst ON_RE =\n /(?:app|router|hono)\\s*\\.\\s*on\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*,\\s*['\"`]([^'\"`]+)['\"`]/g;\n\n// app.route('/api', subApp)\nconst ROUTE_GROUP_RE =\n /(?:app|router|hono)\\s*\\.\\s*route\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*,\\s*([A-Za-z][\\w]*)/g;\n\n// app.use('/path', middleware) — path-scoped\nconst MIDDLEWARE_PATH_RE =\n /(?:app|router|hono)\\s*\\.\\s*use\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*,\\s*([A-Za-z][\\w.]*(?:\\s*\\(\\s*[^)]*\\))?)/g;\n\n// app.use(middleware()) — global (no path string as first arg)\nconst MIDDLEWARE_GLOBAL_RE =\n /(?:app|router|hono)\\s*\\.\\s*use\\s*\\(\\s*([A-Za-z][\\w.]*(?:\\s*\\(\\s*[^)]*\\))?)\\s*[,)]/g;\n\n// app.basePath('/v1')\nconst BASEPATH_RE =\n /(?:app|router|hono)\\s*\\.\\s*basePath\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n\nexport interface HonoRoute {\n method: string;\n path: string;\n}\n\nexport interface HonoMiddleware {\n path: string | null;\n name: string;\n}\n\n/** Extract route definitions from Hono source code. */\nexport function extractHonoRoutes(source: string): HonoRoute[] {\n const routes: HonoRoute[] = [];\n\n // Shorthand: app.get('/path', handler)\n const shortRe = new RegExp(ROUTE_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = shortRe.exec(source)) !== null) {\n routes.push({\n method: match[1].toUpperCase(),\n path: match[2],\n });\n }\n\n // app.on('METHOD', '/path', handler)\n const onRe = new RegExp(ON_RE.source, 'g');\n while ((match = onRe.exec(source)) !== null) {\n routes.push({\n method: match[1].toUpperCase(),\n path: match[2],\n });\n }\n\n // app.route('/prefix', subApp) — mount as route group\n const groupRe = new RegExp(ROUTE_GROUP_RE.source, 'g');\n while ((match = groupRe.exec(source)) !== null) {\n routes.push({\n method: 'USE',\n path: match[1],\n });\n }\n\n return routes;\n}\n\n/** Extract middleware use() calls from Hono source code. */\nexport function extractHonoMiddleware(source: string): HonoMiddleware[] {\n const middlewares: HonoMiddleware[] = [];\n\n // Path-scoped: app.use('/api/*', cors())\n const pathRe = new RegExp(MIDDLEWARE_PATH_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = pathRe.exec(source)) !== null) {\n middlewares.push({\n path: match[1],\n name: match[2].trim(),\n });\n }\n\n // Global: app.use(logger())\n const globalRe = new RegExp(MIDDLEWARE_GLOBAL_RE.source, 'g');\n while ((match = globalRe.exec(source)) !== null) {\n const name = match[1].trim();\n // Skip if it looks like a path string (already captured above)\n if (/^['\"`]/.test(name)) continue;\n middlewares.push({\n path: null,\n name,\n });\n }\n\n return middlewares;\n}\n\nexport class HonoPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'hono',\n version: '1.0.0',\n priority: 25,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if ('hono' in deps) return true;\n }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n return 'hono' in deps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'hono_route', category: 'hono', description: 'Hono route handler' },\n { name: 'hono_middleware', category: 'hono', description: 'Hono middleware usage' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (!['typescript', 'javascript'].includes(language)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = { status: 'ok', symbols: [], routes: [], edges: [] };\n\n const routes = extractHonoRoutes(source);\n if (routes.length > 0) {\n result.frameworkRole = 'hono_route';\n for (const route of routes) {\n result.routes!.push({\n method: route.method,\n uri: route.path,\n });\n }\n }\n\n const middlewares = extractHonoMiddleware(source);\n if (middlewares.length > 0) {\n result.frameworkRole = result.frameworkRole ?? 'hono_middleware';\n for (const mw of middlewares) {\n result.routes!.push({\n method: 'USE',\n uri: mw.path ?? '/',\n });\n }\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n return ok(edges);\n }\n}\n","/**\n * SocketIoPlugin — detects Socket.io projects and extracts event listeners,\n * event emitters, and namespace definitions.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\n// socket.on('eventName', handler) or io.on('connection', ...)\nconst LISTENER_RE =\n /(?:socket|io|server|namespace)\\s*\\.\\s*on\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n\n// socket.emit('eventName', ...) or io.emit(...) or socket.broadcast.emit(...)\nconst EMITTER_RE =\n /(?:socket|io|server|namespace)(?:\\.broadcast)?\\s*\\.\\s*emit\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n\n// io.of('/namespace')\nconst NAMESPACE_RE =\n /(?:io|server)\\s*\\.\\s*of\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n\nexport interface SocketEvent {\n name: string;\n type: 'listener' | 'emitter';\n}\n\n/** Extract event listeners and emitters from Socket.io source code. */\nexport function extractSocketEvents(source: string): SocketEvent[] {\n const events: SocketEvent[] = [];\n\n const listenerRe = new RegExp(LISTENER_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = listenerRe.exec(source)) !== null) {\n events.push({ name: match[1], type: 'listener' });\n }\n\n const emitterRe = new RegExp(EMITTER_RE.source, 'g');\n while ((match = emitterRe.exec(source)) !== null) {\n events.push({ name: match[1], type: 'emitter' });\n }\n\n return events;\n}\n\n/** Extract namespace definitions from Socket.io source code. */\nexport function extractSocketNamespaces(source: string): string[] {\n const namespaces: string[] = [];\n const re = new RegExp(NAMESPACE_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n namespaces.push(match[1]);\n }\n return namespaces;\n}\n\nexport class SocketIoPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'socketio',\n version: '1.0.0',\n priority: 25,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if ('socket.io' in deps) return true;\n }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n return 'socket.io' in deps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'socketio_event', category: 'socketio', description: 'Event listener/emitter' },\n { name: 'socketio_namespace', category: 'socketio', description: 'Namespace definition' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (!['typescript', 'javascript'].includes(language)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = { status: 'ok', symbols: [], routes: [], edges: [] };\n\n const events = extractSocketEvents(source);\n if (events.length > 0) {\n result.frameworkRole = 'socketio_handler';\n for (const evt of events) {\n result.routes!.push({\n method: 'EVENT',\n uri: evt.name,\n });\n }\n }\n\n const namespaces = extractSocketNamespaces(source);\n if (namespaces.length > 0) {\n result.frameworkRole = result.frameworkRole ?? 'socketio_handler';\n for (const ns of namespaces) {\n result.routes!.push({\n method: 'NAMESPACE',\n uri: ns,\n });\n }\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n return ok(edges);\n }\n}\n","/**\n * ZustandReduxPlugin — Framework plugin for Zustand and Redux Toolkit stores.\n *\n * Extracts:\n * - Zustand: create()/createStore() → store name, state fields, actions\n * - Redux Toolkit: createSlice() → slice name, initial state fields, reducers, extraReducers\n * - useSelector/useStore hooks → which store/slice is consumed\n * - dispatch() calls → which actions are dispatched\n *\n * Supports Zustand 4+, Redux Toolkit 1.9+.\n */\nimport { ok } from 'neverthrow';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\nimport type { TraceMcpResult } from '../../../../errors.js';\n\nexport class ZustandReduxPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'zustand-redux',\n version: '1.0.0',\n priority: 35,\n dependencies: [],\n };\n\n private hasZustand = false;\n private hasRedux = false;\n\n detect(ctx: ProjectContext): boolean {\n const deps = {\n ...(ctx.packageJson?.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson?.devDependencies as Record<string, string> | undefined),\n };\n this.hasZustand = 'zustand' in deps;\n this.hasRedux = '@reduxjs/toolkit' in deps || 'redux-toolkit' in deps;\n return this.hasZustand || this.hasRedux;\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'zustand_store', category: 'state-management', description: 'Zustand store definition' },\n { name: 'redux_slice', category: 'state-management', description: 'Redux Toolkit slice definition' },\n { name: 'dispatches_action', category: 'state-management', description: 'Component dispatches a Redux/Zustand action' },\n { name: 'selects_state', category: 'state-management', description: 'Component selects state from store' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'typescript' && language !== 'javascript') {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const routes: RawRoute[] = [];\n let frameworkRole: string | undefined;\n\n // Zustand stores\n const zustandStores = extractZustandStores(source);\n if (zustandStores.length > 0) {\n frameworkRole = 'zustand_store';\n for (const store of zustandStores) {\n routes.push({\n method: 'STORE',\n uri: `zustand:${store.name}`,\n handler: store.name,\n metadata: {\n stateFields: store.stateFields,\n actions: store.actions,\n },\n });\n }\n }\n\n // Redux slices\n const reduxSlices = extractReduxSlices(source);\n if (reduxSlices.length > 0) {\n frameworkRole = 'redux_slice';\n for (const slice of reduxSlices) {\n routes.push({\n method: 'SLICE',\n uri: `redux:${slice.name}`,\n handler: slice.varName,\n metadata: {\n reducers: slice.reducers,\n initialStateFields: slice.initialStateFields,\n },\n });\n }\n }\n\n // Dispatched actions\n const dispatches = extractDispatches(source);\n for (const d of dispatches) {\n routes.push({\n method: 'DISPATCH',\n uri: `action:${d}`,\n });\n }\n\n if (routes.length === 0) return ok({ status: 'ok', symbols: [] });\n\n return ok({\n status: 'ok',\n symbols: [],\n routes,\n frameworkRole,\n });\n }\n\n resolveEdges(_ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n\n// ── Zustand extraction ─────────────────────────────────────────────────────\n\nexport interface ZustandStore {\n name: string;\n stateFields: string[];\n actions: string[];\n}\n\n/**\n * Extract Zustand store definitions from source code.\n * Handles: create(), create<State>()(), createStore(), zustand's create with set/get.\n */\nexport function extractZustandStores(source: string): ZustandStore[] {\n const stores: ZustandStore[] = [];\n\n // Pattern: export const useXxxStore = create((...) => ({ ... }))\n // or: export const useXxxStore = create<XxxState>()((...) => ({ ... }))\n const storeRegex = /(?:export\\s+)?(?:const|let)\\s+(use\\w+Store|\\w+Store)\\s*=\\s*create(?:<[^>]+>)?(?:\\(\\))?\\s*\\(/g;\n let match: RegExpExecArray | null;\n\n while ((match = storeRegex.exec(source)) !== null) {\n const storeName = match[1];\n\n // Find the body of the create() call\n const startPos = match.index + match[0].length;\n const body = extractParenBody(source, startPos);\n\n // Extract state fields: key: value (not functions)\n const stateFields: string[] = [];\n const actions: string[] = [];\n\n // Match property assignments: fieldName: value\n const propRegex = /(\\w+)\\s*:\\s*(?!(?:async\\s+)?\\()/g;\n let propMatch: RegExpExecArray | null;\n while ((propMatch = propRegex.exec(body)) !== null) {\n const name = propMatch[1];\n if (!['set', 'get', 'subscribe', 'getState', 'setState', 'destroy'].includes(name)) {\n stateFields.push(name);\n }\n }\n\n // Match actions (functions): actionName: (args) => ..., or actionName(args) { ... }\n const actionRegex = /(\\w+)\\s*:\\s*(?:async\\s+)?\\([^)]*\\)\\s*=>/g;\n let actionMatch: RegExpExecArray | null;\n while ((actionMatch = actionRegex.exec(body)) !== null) {\n actions.push(actionMatch[1]);\n }\n\n stores.push({ name: storeName, stateFields, actions });\n }\n\n return stores;\n}\n\n// ── Redux Toolkit extraction ───────────────────────────────────────────────\n\nexport interface ReduxSlice {\n name: string;\n varName: string;\n reducers: string[];\n initialStateFields: string[];\n}\n\n/**\n * Extract Redux Toolkit createSlice() definitions.\n */\nexport function extractReduxSlices(source: string): ReduxSlice[] {\n const slices: ReduxSlice[] = [];\n\n // Pattern: const xxxSlice = createSlice({ name: 'xxx', initialState: { ... }, reducers: { ... } })\n const sliceRegex = /(?:export\\s+)?(?:const|let)\\s+(\\w+)\\s*=\\s*createSlice\\s*\\(\\s*\\{/g;\n let match: RegExpExecArray | null;\n\n while ((match = sliceRegex.exec(source)) !== null) {\n const varName = match[1];\n const startPos = match.index + match[0].length - 1; // at the opening {\n const body = extractBraceBody(source, startPos);\n\n // Extract slice name\n const nameMatch = body.match(/name\\s*:\\s*['\"]([^'\"]+)['\"]/);\n const name = nameMatch?.[1] ?? varName.replace(/Slice$/, '');\n\n // Extract reducer names\n const reducers: string[] = [];\n const reducersMatch = body.match(/reducers\\s*:\\s*\\{/);\n if (reducersMatch) {\n const reducersStart = body.indexOf('{', reducersMatch.index! + reducersMatch[0].length - 1);\n const reducersBody = extractBraceBody(body, reducersStart);\n const reducerRegex = /(\\w+)\\s*(?::\\s*\\(|(?:\\s*\\([^)]*\\)))/g;\n let rMatch: RegExpExecArray | null;\n while ((rMatch = reducerRegex.exec(reducersBody)) !== null) {\n const rName = rMatch[1];\n if (!['state', 'action', 'payload', 'type'].includes(rName)) {\n reducers.push(rName);\n }\n }\n }\n\n // Extract initial state fields\n const initialStateFields: string[] = [];\n const stateMatch = body.match(/initialState\\s*:\\s*\\{/);\n if (stateMatch) {\n const stateStart = body.indexOf('{', stateMatch.index! + stateMatch[0].length - 1);\n const stateBody = extractBraceBody(body, stateStart);\n const fieldRegex = /(\\w+)\\s*:/g;\n let fMatch: RegExpExecArray | null;\n while ((fMatch = fieldRegex.exec(stateBody)) !== null) {\n initialStateFields.push(fMatch[1]);\n }\n }\n\n slices.push({ name, varName, reducers, initialStateFields });\n }\n\n return slices;\n}\n\n// ── Dispatch extraction ────────────────────────────────────────────────────\n\n/**\n * Extract dispatched action names from dispatch() calls and Zustand store method calls.\n */\nexport function extractDispatches(source: string): string[] {\n const dispatches: string[] = [];\n\n // Redux: dispatch(actionName()) or dispatch(sliceName.actions.actionName())\n const dispatchRegex = /dispatch\\(\\s*(\\w+)\\s*\\(/g;\n let match: RegExpExecArray | null;\n while ((match = dispatchRegex.exec(source)) !== null) {\n dispatches.push(match[1]);\n }\n\n // Redux: dispatch(slice.actions.actionName(...))\n const sliceDispatchRegex = /dispatch\\(\\s*\\w+\\.actions\\.(\\w+)/g;\n while ((match = sliceDispatchRegex.exec(source)) !== null) {\n dispatches.push(match[1]);\n }\n\n return [...new Set(dispatches)];\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────\n\nfunction extractParenBody(source: string, pos: number): string {\n let depth = 1;\n let i = pos;\n while (i < source.length && depth > 0) {\n if (source[i] === '(') depth++;\n else if (source[i] === ')') depth--;\n i++;\n }\n return source.slice(pos, i - 1);\n}\n\nfunction extractBraceBody(source: string, pos: number): string {\n let depth = 0;\n let start = pos;\n while (start < source.length && source[start] !== '{') start++;\n if (start >= source.length) return '';\n depth = 1;\n let i = start + 1;\n while (i < source.length && depth > 0) {\n if (source[i] === '{') depth++;\n else if (source[i] === '}') depth--;\n i++;\n }\n return source.slice(start + 1, i - 1);\n}\n","/**\n * N8nPlugin — comprehensive n8n workflow indexing.\n *\n * Extracts and models the full structure of n8n workflow JSON files:\n * - All node categories: triggers, actions, flow control, data transforms, AI/LangChain\n * - Typed connections (main, error, ai_languageModel, ai_tool, ai_memory, etc.)\n * - Webhook/form/schedule routes as discoverable endpoints\n * - Sub-workflow calls with cross-file resolution\n * - HTTP request external dependencies\n * - Credential references with full ID/name\n * - Implicit data dependencies via expression parsing ($node[\"Name\"])\n * - Sticky notes as documentation\n * - Workflow-level settings (errorWorkflow, timezone, callerPolicy)\n * - Node-level error handling (continueOnFail, retryOnFail, onError)\n * - Custom n8n node package detection\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n RawRoute,\n RawSymbol,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\n// ── Types ────────────────────────────────────────────────────────────────\n\nexport interface N8nCredentialRef {\n id: string | null;\n name: string;\n}\n\nexport interface N8nNode {\n id?: string;\n name: string;\n type: string;\n position: [number, number];\n parameters?: Record<string, unknown>;\n typeVersion?: number;\n credentials?: Record<string, N8nCredentialRef>;\n disabled?: boolean;\n notes?: string;\n notesInFlow?: boolean;\n retryOnFail?: boolean;\n maxTries?: number;\n waitBetweenTries?: number;\n continueOnFail?: boolean;\n onError?: 'continueErrorOutput' | 'continueRegularOutput' | 'stopWorkflow';\n alwaysOutputData?: boolean;\n executeOnce?: boolean;\n webhookId?: string;\n color?: number;\n}\n\nexport interface N8nConnectionTarget {\n node: string;\n type: string; // \"main\", \"ai_languageModel\", \"ai_tool\", etc.\n index: number;\n}\n\nexport interface N8nConnection {\n sourceNode: string;\n sourceOutput: number;\n targetNode: string;\n targetInput: number;\n connectionType: string; // \"main\", \"ai_languageModel\", \"ai_tool\", etc.\n}\n\nexport interface N8nWorkflowSettings {\n timezone?: string;\n errorWorkflow?: string;\n callerIds?: string;\n callerPolicy?: 'any' | 'none' | 'workflowsFromAList';\n saveDataErrorExecution?: string;\n saveDataSuccessExecution?: string;\n saveManualExecutions?: string | boolean;\n saveExecutionProgress?: string | boolean;\n executionTimeout?: number;\n executionOrder?: 'v0' | 'v1';\n}\n\nexport interface N8nWorkflow {\n id?: string;\n name?: string;\n nodes: N8nNode[];\n connections: Record<string, Record<string, Array<Array<N8nConnectionTarget>>>>;\n active?: boolean;\n settings?: N8nWorkflowSettings;\n staticData?: Record<string, unknown> | null;\n pinData?: Record<string, unknown[]>;\n tags?: string[] | Array<{ name: string }>;\n meta?: { templateId?: string; instanceId?: string };\n}\n\n// ── Node classification ──────────────────────────────────────────────────\n\nconst TRIGGER_TYPES = new Set([\n // Core triggers\n 'n8n-nodes-base.webhook',\n 'n8n-nodes-base.scheduleTrigger',\n 'n8n-nodes-base.cron',\n 'n8n-nodes-base.cronTrigger',\n 'n8n-nodes-base.manualTrigger',\n 'n8n-nodes-base.errorTrigger',\n 'n8n-nodes-base.workflowTrigger',\n 'n8n-nodes-base.executeWorkflowTrigger',\n 'n8n-nodes-base.emailReadImap',\n 'n8n-nodes-base.formTrigger',\n 'n8n-nodes-base.sseTrigger',\n 'n8n-nodes-base.rssFeedReadTrigger',\n // AI triggers\n '@n8n/n8n-nodes-langchain.chatTrigger',\n '@n8n/n8n-nodes-langchain.manualChatTrigger',\n '@n8n/n8n-nodes-langchain.mcpTrigger',\n // Common service triggers\n 'n8n-nodes-base.gmailTrigger',\n 'n8n-nodes-base.telegramTrigger',\n 'n8n-nodes-base.slackTrigger',\n 'n8n-nodes-base.stripeTrigger',\n 'n8n-nodes-base.githubTrigger',\n 'n8n-nodes-base.gitlabTrigger',\n 'n8n-nodes-base.linearTrigger',\n 'n8n-nodes-base.asanaTrigger',\n 'n8n-nodes-base.airtableTrigger',\n 'n8n-nodes-base.postgresTrigger',\n 'n8n-nodes-base.redisTrigger',\n 'n8n-nodes-base.whatsAppTrigger',\n 'n8n-nodes-base.facebookTrigger',\n 'n8n-nodes-base.calTrigger',\n 'n8n-nodes-base.calendlyTrigger',\n]);\n\nconst CODE_TYPES = new Set([\n 'n8n-nodes-base.code',\n 'n8n-nodes-base.function',\n 'n8n-nodes-base.functionItem',\n '@n8n/n8n-nodes-langchain.code',\n]);\n\nconst FLOW_CONTROL_TYPES = new Set([\n 'n8n-nodes-base.if',\n 'n8n-nodes-base.switch',\n 'n8n-nodes-base.merge',\n 'n8n-nodes-base.splitInBatches',\n 'n8n-nodes-base.wait',\n 'n8n-nodes-base.filter',\n 'n8n-nodes-base.limit',\n 'n8n-nodes-base.noOp',\n 'n8n-nodes-base.respondToWebhook',\n 'n8n-nodes-base.compareDatasets',\n 'n8n-nodes-base.executionData',\n]);\n\nconst DATA_TRANSFORM_TYPES = new Set([\n 'n8n-nodes-base.set',\n 'n8n-nodes-base.itemLists',\n 'n8n-nodes-base.splitOut',\n 'n8n-nodes-base.aggregate',\n 'n8n-nodes-base.summarize',\n 'n8n-nodes-base.sort',\n 'n8n-nodes-base.removeDuplicates',\n 'n8n-nodes-base.crypto',\n 'n8n-nodes-base.markdown',\n 'n8n-nodes-base.xml',\n 'n8n-nodes-base.convertToFile',\n 'n8n-nodes-base.extractFromFile',\n 'n8n-nodes-base.aiTransform',\n 'n8n-nodes-base.dateTime',\n 'n8n-nodes-base.html',\n 'n8n-nodes-base.renameKeys',\n]);\n\nconst SUBWORKFLOW_TYPES = new Set([\n 'n8n-nodes-base.executeWorkflow',\n '@n8n/n8n-nodes-langchain.toolWorkflow',\n]);\n\nconst HTTP_REQUEST_TYPES = new Set([\n 'n8n-nodes-base.httpRequest',\n 'n8n-nodes-base.httpRequestTool',\n 'n8n-nodes-base.graphql',\n]);\n\nconst STICKY_NOTE_TYPE = 'n8n-nodes-base.stickyNote';\n\nconst AI_CONNECTION_TYPES = new Set([\n 'ai_agent', 'ai_chain', 'ai_document', 'ai_embedding',\n 'ai_languageModel', 'ai_memory', 'ai_outputParser',\n 'ai_retriever', 'ai_reranker', 'ai_textSplitter',\n 'ai_tool', 'ai_vectorStore',\n]);\n\n// ── Expression dependency parsing ────────────────────────────────────────\n\nconst EXPR_NODE_REF = /\\$node\\s*\\[\\s*['\"]([^'\"]+)['\"]\\s*\\]/g;\nconst EXPR_ITEMS_REF = /\\$items\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n\nexport function extractExpressionDeps(value: unknown, deps: Set<string>): void {\n if (typeof value === 'string') {\n let m: RegExpExecArray | null;\n const re1 = new RegExp(EXPR_NODE_REF.source, 'g');\n while ((m = re1.exec(value)) !== null) deps.add(m[1]);\n const re2 = new RegExp(EXPR_ITEMS_REF.source, 'g');\n while ((m = re2.exec(value)) !== null) deps.add(m[1]);\n } else if (value && typeof value === 'object') {\n for (const v of Object.values(value as Record<string, unknown>)) {\n extractExpressionDeps(v, deps);\n }\n }\n}\n\n// ── Node category classification ─────────────────────────────────────────\n\nexport type N8nNodeCategory =\n | 'trigger' | 'code' | 'flow_control' | 'data_transform'\n | 'ai' | 'subworkflow' | 'http_request' | 'sticky_note' | 'action';\n\nexport function classifyNode(node: N8nNode): N8nNodeCategory {\n if (node.type === STICKY_NOTE_TYPE) return 'sticky_note';\n if (isTriggerNode(node)) return 'trigger';\n if (CODE_TYPES.has(node.type)) return 'code';\n if (FLOW_CONTROL_TYPES.has(node.type)) return 'flow_control';\n if (DATA_TRANSFORM_TYPES.has(node.type)) return 'data_transform';\n if (SUBWORKFLOW_TYPES.has(node.type)) return 'subworkflow';\n if (HTTP_REQUEST_TYPES.has(node.type)) return 'http_request';\n if (isAiNode(node)) return 'ai';\n return 'action';\n}\n\nexport function isTriggerNode(node: N8nNode): boolean {\n return TRIGGER_TYPES.has(node.type)\n || node.type.toLowerCase().includes('trigger');\n}\n\nexport function isAiNode(node: N8nNode): boolean {\n return node.type.startsWith('@n8n/n8n-nodes-langchain.')\n || node.type.includes('langchain');\n}\n\n// ── Framework role classification ────────────────────────────────────────\n\nfunction classifyWorkflowRole(workflow: N8nWorkflow): string {\n const hasAi = workflow.nodes.some(isAiNode);\n const hasTrigger = workflow.nodes.some(isTriggerNode);\n const hasWebhook = workflow.nodes.some((n) => n.type === 'n8n-nodes-base.webhook');\n const hasSchedule = workflow.nodes.some((n) =>\n n.type === 'n8n-nodes-base.scheduleTrigger' || n.type === 'n8n-nodes-base.cron',\n );\n const isErrorHandler = workflow.nodes.some((n) => n.type === 'n8n-nodes-base.errorTrigger');\n const isSubWorkflow = workflow.nodes.some((n) =>\n n.type === 'n8n-nodes-base.executeWorkflowTrigger' || n.type === 'n8n-nodes-base.workflowTrigger',\n );\n\n if (isErrorHandler) return 'n8n_error_workflow';\n if (hasAi) return 'n8n_ai_workflow';\n if (isSubWorkflow) return 'n8n_subworkflow';\n if (hasWebhook) return 'n8n_webhook_workflow';\n if (hasSchedule) return 'n8n_scheduled_workflow';\n if (hasTrigger) return 'n8n_triggered_workflow';\n return 'n8n_workflow';\n}\n\n// ── Parsing ──────────────────────────────────────────────────────────────\n\nexport function parseN8nWorkflow(content: Buffer): N8nWorkflow | null {\n try {\n const json = JSON.parse(content.toString('utf-8'));\n if (json && Array.isArray(json.nodes) && json.connections && typeof json.connections === 'object') {\n return json as N8nWorkflow;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n// ── Connection extraction ────────────────────────────────────────────────\n\nexport function extractConnections(workflow: N8nWorkflow): N8nConnection[] {\n const connections: N8nConnection[] = [];\n for (const [sourceName, outputs] of Object.entries(workflow.connections)) {\n for (const [connType, outputConns] of Object.entries(outputs)) {\n for (let outputIdx = 0; outputIdx < outputConns.length; outputIdx++) {\n const targets = outputConns[outputIdx];\n if (!targets) continue;\n for (const target of targets) {\n connections.push({\n sourceNode: sourceName,\n sourceOutput: outputIdx,\n targetNode: target.node,\n targetInput: target.index,\n connectionType: connType,\n });\n }\n }\n }\n }\n return connections;\n}\n\n// ── Trigger extraction ───────────────────────────────────────────────────\n\nexport function extractTriggers(workflow: N8nWorkflow): N8nNode[] {\n return workflow.nodes.filter(isTriggerNode);\n}\n\n// ── Route extraction (webhooks, schedules, forms, workflow triggers) ─────\n\nexport function extractRoutes(workflow: N8nWorkflow): RawRoute[] {\n const routes: RawRoute[] = [];\n for (const node of workflow.nodes) {\n if (node.disabled) continue;\n\n // Webhook endpoints\n if (node.type === 'n8n-nodes-base.webhook' && node.parameters) {\n const webhookPath = (node.parameters.path as string) ?? '/';\n const method = ((node.parameters.httpMethod as string) ?? 'GET').toUpperCase();\n routes.push({\n method,\n uri: webhookPath.startsWith('/') ? webhookPath : `/${webhookPath}`,\n name: node.name,\n metadata: { n8nNodeType: node.type, webhookId: node.webhookId },\n });\n }\n\n // Form trigger endpoints\n if (node.type === 'n8n-nodes-base.formTrigger' && node.parameters) {\n const formPath = (node.parameters.path as string) ?? (node.parameters.formTitle as string) ?? '/form';\n routes.push({\n method: 'FORM',\n uri: formPath.startsWith('/') ? formPath : `/${formPath}`,\n name: node.name,\n metadata: { n8nNodeType: node.type },\n });\n }\n\n // Schedule triggers as CRON routes\n if ((node.type === 'n8n-nodes-base.scheduleTrigger' || node.type === 'n8n-nodes-base.cron') && node.parameters) {\n const rule = node.parameters.rule as Record<string, unknown> | undefined;\n const cronExpr = (node.parameters.cronExpression as string)\n ?? (rule ? JSON.stringify(rule) : 'schedule');\n routes.push({\n method: 'CRON',\n uri: cronExpr,\n name: node.name,\n metadata: { n8nNodeType: node.type },\n });\n }\n\n // Sub-workflow entry points\n if (node.type === 'n8n-nodes-base.executeWorkflowTrigger' || node.type === 'n8n-nodes-base.workflowTrigger') {\n routes.push({\n method: 'WORKFLOW',\n uri: `trigger:${node.name}`,\n name: node.name,\n metadata: { n8nNodeType: node.type },\n });\n }\n\n // Chat/MCP triggers\n if (node.type === '@n8n/n8n-nodes-langchain.chatTrigger'\n || node.type === '@n8n/n8n-nodes-langchain.manualChatTrigger') {\n routes.push({\n method: 'CHAT',\n uri: `/chat/${node.name.replace(/\\s+/g, '-').toLowerCase()}`,\n name: node.name,\n metadata: { n8nNodeType: node.type },\n });\n }\n\n if (node.type === '@n8n/n8n-nodes-langchain.mcpTrigger') {\n routes.push({\n method: 'MCP',\n uri: `/mcp/${node.name.replace(/\\s+/g, '-').toLowerCase()}`,\n name: node.name,\n metadata: { n8nNodeType: node.type },\n });\n }\n }\n return routes;\n}\n\n// ── Code node extraction ─────────────────────────────────────────────────\n\nexport function extractCodeNodes(workflow: N8nWorkflow): Array<{\n node: N8nNode;\n code: string;\n language: string;\n nodeDeps: string[];\n}> {\n const results: Array<{ node: N8nNode; code: string; language: string; nodeDeps: string[] }> = [];\n for (const node of workflow.nodes) {\n if (!CODE_TYPES.has(node.type) || !node.parameters) continue;\n const code = (node.parameters.jsCode as string)\n ?? (node.parameters.functionCode as string)\n ?? (node.parameters.code as string)\n ?? (node.parameters.pythonCode as string)\n ?? '';\n if (!code.trim()) continue;\n\n const lang = (node.parameters.language as string) ?? 'javascript';\n const deps = new Set<string>();\n extractExpressionDeps(code, deps);\n results.push({ node, code, language: lang, nodeDeps: [...deps] });\n }\n return results;\n}\n\n// ── Sub-workflow extraction ──────────────────────────────────────────────\n\nexport function extractSubWorkflowCalls(workflow: N8nWorkflow): Array<{\n node: N8nNode;\n workflowId: string;\n source: 'id' | 'expression';\n}> {\n const calls: Array<{ node: N8nNode; workflowId: string; source: 'id' | 'expression' }> = [];\n for (const node of workflow.nodes) {\n if (!SUBWORKFLOW_TYPES.has(node.type) || !node.parameters) continue;\n\n const rawId = node.parameters.workflowId;\n let wfId = '';\n let source: 'id' | 'expression' = 'id';\n\n if (typeof rawId === 'string') {\n wfId = rawId;\n } else if (rawId && typeof rawId === 'object') {\n const obj = rawId as Record<string, unknown>;\n wfId = (obj.value as string) ?? '';\n if (obj.__rl === true && obj.mode === 'expression') source = 'expression';\n }\n\n if (wfId) calls.push({ node, workflowId: wfId, source });\n }\n return calls;\n}\n\n// ── HTTP request extraction ──────────────────────────────────────────────\n\nexport function extractHttpRequests(workflow: N8nWorkflow): Array<{\n node: N8nNode;\n url: string;\n method: string;\n authentication?: string;\n}> {\n const requests: Array<{ node: N8nNode; url: string; method: string; authentication?: string }> = [];\n for (const node of workflow.nodes) {\n if (!HTTP_REQUEST_TYPES.has(node.type) || !node.parameters) continue;\n const url = (node.parameters.url as string) ?? '';\n const method = ((node.parameters.method as string)\n ?? (node.parameters.requestMethod as string)\n ?? 'GET').toUpperCase();\n if (!url) continue;\n\n const authentication = node.parameters.authentication as string | undefined;\n requests.push({ node, url, method, ...(authentication ? { authentication } : {}) });\n }\n return requests;\n}\n\n// ── Sticky notes extraction ──────────────────────────────────────────────\n\nexport function extractStickyNotes(workflow: N8nWorkflow): Array<{\n node: N8nNode;\n content: string;\n width?: number;\n height?: number;\n color?: number;\n}> {\n const notes: Array<{ node: N8nNode; content: string; width?: number; height?: number; color?: number }> = [];\n for (const node of workflow.nodes) {\n if (node.type !== STICKY_NOTE_TYPE || !node.parameters) continue;\n const content = (node.parameters.content as string) ?? '';\n if (!content.trim()) continue;\n notes.push({\n node,\n content,\n width: node.parameters.width as number | undefined,\n height: node.parameters.height as number | undefined,\n color: node.color ?? (node.parameters.color as number | undefined),\n });\n }\n return notes;\n}\n\n// ── AI node extraction ───────────────────────────────────────────────────\n\nexport type AiNodeRole = 'agent' | 'chain' | 'llm' | 'embedding' | 'memory'\n | 'vector_store' | 'retriever' | 'tool' | 'output_parser' | 'document_loader'\n | 'text_splitter' | 'reranker' | 'standalone';\n\nexport function classifyAiNode(nodeType: string): AiNodeRole {\n const t = nodeType.replace('@n8n/n8n-nodes-langchain.', '');\n if (t.startsWith('agent') || t === 'agent') return 'agent';\n if (t.startsWith('chain')) return 'chain';\n if (t.startsWith('lm') || t.startsWith('lmChat')) return 'llm';\n if (t.startsWith('embeddings')) return 'embedding';\n if (t.startsWith('memory')) return 'memory';\n if (t.startsWith('vectorStore')) return 'vector_store';\n if (t.startsWith('retriever')) return 'retriever';\n if (t.startsWith('tool') || t.endsWith('Tool')) return 'tool';\n if (t.startsWith('outputParser')) return 'output_parser';\n if (t.startsWith('document')) return 'document_loader';\n if (t.startsWith('textSplitter')) return 'text_splitter';\n if (t.startsWith('reranker')) return 'reranker';\n return 'standalone';\n}\n\nexport function extractAiNodes(workflow: N8nWorkflow): Array<{\n node: N8nNode;\n role: AiNodeRole;\n model?: string;\n}> {\n const results: Array<{ node: N8nNode; role: AiNodeRole; model?: string }> = [];\n for (const node of workflow.nodes) {\n if (!isAiNode(node)) continue;\n const role = classifyAiNode(node.type);\n let model: string | undefined;\n if (node.parameters) {\n model = (node.parameters.model as string)\n ?? (node.parameters.modelId as string)\n ?? (node.parameters.modelName as string)\n ?? undefined;\n }\n results.push({ node, role, ...(model ? { model } : {}) });\n }\n return results;\n}\n\n// ── Expression dependency extraction (workflow-wide) ─────────────────────\n\nexport function extractAllExpressionDeps(workflow: N8nWorkflow): Map<string, Set<string>> {\n const nodeDeps = new Map<string, Set<string>>();\n for (const node of workflow.nodes) {\n if (!node.parameters) continue;\n const deps = new Set<string>();\n extractExpressionDeps(node.parameters, deps);\n // Remove self-references\n deps.delete(node.name);\n if (deps.size > 0) {\n nodeDeps.set(node.name, deps);\n }\n }\n return nodeDeps;\n}\n\n// ── Credential extraction (full details) ─────────────────────────────────\n\nexport interface CredentialUsage {\n node: N8nNode;\n credentialType: string;\n credentialId: string | null;\n credentialName: string;\n}\n\nexport function extractCredentialUsages(workflow: N8nWorkflow): CredentialUsage[] {\n const usages: CredentialUsage[] = [];\n for (const node of workflow.nodes) {\n if (!node.credentials) continue;\n for (const [credType, credRef] of Object.entries(node.credentials)) {\n const ref = credRef as N8nCredentialRef | undefined;\n usages.push({\n node,\n credentialType: credType,\n credentialId: ref?.id ?? null,\n credentialName: ref?.name ?? credType,\n });\n }\n }\n return usages;\n}\n\n// ── Flow control analysis ────────────────────────────────────────────────\n\nexport interface FlowControlInfo {\n node: N8nNode;\n controlType: 'conditional' | 'switch' | 'merge' | 'loop' | 'wait' | 'filter' | 'respond' | 'other';\n outputCount?: number;\n mergeMode?: string;\n batchSize?: number;\n}\n\nexport function extractFlowControl(workflow: N8nWorkflow, connections: N8nConnection[]): FlowControlInfo[] {\n const results: FlowControlInfo[] = [];\n for (const node of workflow.nodes) {\n if (!FLOW_CONTROL_TYPES.has(node.type)) continue;\n\n const outputs = connections.filter((c) => c.sourceNode === node.name);\n const maxOutput = outputs.reduce((max, c) => Math.max(max, c.sourceOutput), -1);\n\n let controlType: FlowControlInfo['controlType'] = 'other';\n let mergeMode: string | undefined;\n let batchSize: number | undefined;\n\n switch (node.type) {\n case 'n8n-nodes-base.if':\n controlType = 'conditional';\n break;\n case 'n8n-nodes-base.switch':\n controlType = 'switch';\n break;\n case 'n8n-nodes-base.merge':\n controlType = 'merge';\n mergeMode = (node.parameters?.mode as string) ?? 'append';\n break;\n case 'n8n-nodes-base.splitInBatches':\n controlType = 'loop';\n batchSize = (node.parameters?.batchSize as number) ?? 10;\n break;\n case 'n8n-nodes-base.wait':\n controlType = 'wait';\n break;\n case 'n8n-nodes-base.filter':\n case 'n8n-nodes-base.limit':\n controlType = 'filter';\n break;\n case 'n8n-nodes-base.respondToWebhook':\n controlType = 'respond';\n break;\n }\n\n results.push({\n node,\n controlType,\n outputCount: maxOutput + 1,\n ...(mergeMode ? { mergeMode } : {}),\n ...(batchSize ? { batchSize } : {}),\n });\n }\n return results;\n}\n\n// ── Plugin ───────────────────────────────────────────────────────────────\n\nexport class N8nPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'n8n',\n version: '2.0.0',\n priority: 30,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if (Object.keys(deps).some((k) =>\n k.startsWith('n8n-nodes') || k === 'n8n-workflow' || k === 'n8n-core',\n )) {\n return true;\n }\n }\n\n try {\n if (fs.existsSync(path.join(ctx.rootPath, '.n8n'))) return true;\n } catch { /* ignore */ }\n\n const searchDirs = ['workflows', 'n8n', '.n8n', '.'];\n for (const dir of searchDirs) {\n try {\n const fullDir = path.join(ctx.rootPath, dir);\n if (!fs.existsSync(fullDir) || !fs.statSync(fullDir).isDirectory()) continue;\n const files = fs.readdirSync(fullDir).filter((f) => f.endsWith('.json'));\n for (const file of files.slice(0, 5)) {\n try {\n const content = fs.readFileSync(path.join(fullDir, file));\n if (parseN8nWorkflow(content)) return true;\n } catch { /* ignore */ }\n }\n } catch { /* ignore */ }\n }\n\n return ctx.configFiles.some(\n (f) => f.includes('n8n') || f.includes('.n8n'),\n );\n }\n\n registerSchema() {\n return {\n nodeTypes: [\n { name: 'n8n_workflow' },\n { name: 'n8n_node' },\n { name: 'n8n_trigger' },\n { name: 'n8n_webhook' },\n { name: 'n8n_code_node' },\n { name: 'n8n_subworkflow_call' },\n { name: 'n8n_ai_node' },\n { name: 'n8n_flow_control' },\n { name: 'n8n_data_transform' },\n { name: 'n8n_sticky_note' },\n ],\n edgeTypes: [\n { name: 'n8n_connection', category: 'n8n', description: 'Data flow between workflow nodes' },\n { name: 'n8n_ai_connection', category: 'n8n', description: 'AI/LangChain typed connection (model, tool, memory, etc.)' },\n { name: 'n8n_error_connection', category: 'n8n', description: 'Error output branch connection' },\n { name: 'n8n_triggers', category: 'n8n', description: 'Trigger initiates workflow execution' },\n { name: 'n8n_webhook_route', category: 'n8n', description: 'Webhook endpoint exposed by workflow' },\n { name: 'n8n_calls_subworkflow', category: 'n8n', description: 'Node invokes another workflow' },\n { name: 'n8n_http_request', category: 'n8n', description: 'HTTP request to external service' },\n { name: 'n8n_uses_credential', category: 'n8n', description: 'Node references a credential' },\n { name: 'n8n_expression_dep', category: 'n8n', description: 'Implicit data dependency via expression ($node[\"Name\"])' },\n { name: 'n8n_error_workflow', category: 'n8n', description: 'Workflow-level error handler reference' },\n { name: 'n8n_conditional_branch', category: 'n8n', description: 'Conditional branch output (IF true/false, Switch cases)' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (language !== 'json' && !filePath.endsWith('.json')) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const workflow = parseN8nWorkflow(content);\n if (!workflow) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const connections = extractConnections(workflow);\n const role = classifyWorkflowRole(workflow);\n const tags = Array.isArray(workflow.tags)\n ? workflow.tags.map((t) => (typeof t === 'string' ? t : t.name))\n : [];\n const stickyNotes = extractStickyNotes(workflow);\n\n const result: FileParseResult = {\n status: 'ok',\n symbols: [],\n edges: [],\n routes: [],\n frameworkRole: role,\n metadata: {\n workflowName: workflow.name ?? path.basename(filePath, '.json'),\n workflowId: workflow.id,\n active: workflow.active ?? false,\n nodeCount: workflow.nodes.length,\n tags,\n settings: workflow.settings ?? {},\n hasPinData: !!(workflow.pinData && Object.keys(workflow.pinData).length > 0),\n hasStaticData: !!(workflow.staticData && Object.keys(workflow.staticData).length > 0),\n templateId: workflow.meta?.templateId,\n stickyNoteCount: stickyNotes.length,\n stickyNotes: stickyNotes.map((s) => ({\n name: s.node.name,\n content: s.content.slice(0, 500),\n })),\n },\n };\n\n const source = content.toString('utf-8');\n const nodeNameSet = new Set(workflow.nodes.map((n) => n.name));\n\n // ── Symbols: one per workflow node ──\n for (const node of workflow.nodes) {\n if (node.type === STICKY_NOTE_TYPE) continue; // skip stickies as symbols\n\n const category = classifyNode(node);\n const byteStart = findNodeByteOffset(source, node.name);\n const byteEnd = byteStart >= 0 ? byteStart + node.name.length + 10 : 0;\n\n const errorHandling: Record<string, unknown> = {};\n if (node.onError) errorHandling.onError = node.onError;\n if (node.continueOnFail) errorHandling.continueOnFail = true;\n if (node.retryOnFail) {\n errorHandling.retryOnFail = true;\n if (node.maxTries) errorHandling.maxTries = node.maxTries;\n if (node.waitBetweenTries) errorHandling.waitBetweenTries = node.waitBetweenTries;\n }\n\n const meta: Record<string, unknown> = {\n n8nNodeType: node.type,\n n8nNodeId: node.id ?? node.name,\n category,\n isDisabled: node.disabled ?? false,\n typeVersion: node.typeVersion,\n position: node.position,\n };\n\n if (Object.keys(errorHandling).length > 0) meta.errorHandling = errorHandling;\n if (node.notes) meta.notes = node.notes;\n if (node.credentials) {\n meta.credentials = Object.entries(node.credentials).map(([type, ref]) => ({\n type,\n id: (ref as N8nCredentialRef)?.id,\n name: (ref as N8nCredentialRef)?.name,\n }));\n }\n if (node.alwaysOutputData) meta.alwaysOutputData = true;\n if (node.executeOnce) meta.executeOnce = true;\n if (node.webhookId) meta.webhookId = node.webhookId;\n\n // AI-specific metadata\n if (isAiNode(node)) {\n meta.aiRole = classifyAiNode(node.type);\n if (node.parameters) {\n const model = (node.parameters.model as string)\n ?? (node.parameters.modelId as string)\n ?? (node.parameters.modelName as string);\n if (model) meta.aiModel = model;\n }\n }\n\n // Flow control metadata\n if (FLOW_CONTROL_TYPES.has(node.type)) {\n const nodeConns = connections.filter((c) => c.sourceNode === node.name);\n const maxOutput = nodeConns.reduce((max, c) => Math.max(max, c.sourceOutput), -1);\n meta.outputCount = maxOutput + 1;\n if (node.type === 'n8n-nodes-base.merge' && node.parameters) {\n meta.mergeMode = (node.parameters.mode as string) ?? 'append';\n }\n if (node.type === 'n8n-nodes-base.splitInBatches' && node.parameters) {\n meta.batchSize = (node.parameters.batchSize as number) ?? 10;\n }\n }\n\n const symbol: RawSymbol = {\n symbolId: `${filePath}::${node.name}#constant`,\n name: node.name,\n kind: 'constant',\n signature: `[n8n:${node.type}${node.typeVersion ? '@' + node.typeVersion : ''}] ${node.name}`,\n byteStart: Math.max(byteStart, 0),\n byteEnd: Math.max(byteEnd, 0),\n metadata: meta,\n };\n result.symbols.push(symbol);\n }\n\n // ── Edges: typed connections ──\n for (const conn of connections) {\n if (!nodeNameSet.has(conn.sourceNode) || !nodeNameSet.has(conn.targetNode)) continue;\n // Skip sticky note connections (shouldn't exist but be safe)\n const srcNode = workflow.nodes.find((n) => n.name === conn.sourceNode);\n if (srcNode?.type === STICKY_NOTE_TYPE) continue;\n\n const isAiConn = AI_CONNECTION_TYPES.has(conn.connectionType);\n let edgeType = 'n8n_connection';\n\n if (isAiConn) {\n edgeType = 'n8n_ai_connection';\n }\n\n result.edges!.push({\n sourceSymbolId: `${filePath}::${conn.sourceNode}#constant`,\n targetSymbolId: `${filePath}::${conn.targetNode}#constant`,\n edgeType,\n metadata: {\n sourceOutput: conn.sourceOutput,\n targetInput: conn.targetInput,\n connectionType: conn.connectionType,\n ...(isAiConn ? { aiConnectionType: conn.connectionType } : {}),\n },\n });\n }\n\n // ── Edges: conditional branch labeling ──\n for (const node of workflow.nodes) {\n if (node.type === 'n8n-nodes-base.if') {\n const nodeConns = connections.filter(\n (c) => c.sourceNode === node.name && c.connectionType === 'main',\n );\n for (const conn of nodeConns) {\n result.edges!.push({\n sourceSymbolId: `${filePath}::${node.name}#constant`,\n targetSymbolId: `${filePath}::${conn.targetNode}#constant`,\n edgeType: 'n8n_conditional_branch',\n metadata: {\n branch: conn.sourceOutput === 0 ? 'true' : 'false',\n outputIndex: conn.sourceOutput,\n },\n });\n }\n } else if (node.type === 'n8n-nodes-base.switch') {\n const nodeConns = connections.filter(\n (c) => c.sourceNode === node.name && c.connectionType === 'main',\n );\n for (const conn of nodeConns) {\n result.edges!.push({\n sourceSymbolId: `${filePath}::${node.name}#constant`,\n targetSymbolId: `${filePath}::${conn.targetNode}#constant`,\n edgeType: 'n8n_conditional_branch',\n metadata: {\n branch: `case_${conn.sourceOutput}`,\n outputIndex: conn.sourceOutput,\n },\n });\n }\n }\n }\n\n // ── Edges: trigger → first connected nodes ──\n const triggers = extractTriggers(workflow);\n for (const trigger of triggers) {\n const triggerConns = connections.filter((c) => c.sourceNode === trigger.name);\n for (const conn of triggerConns) {\n result.edges!.push({\n sourceSymbolId: `${filePath}::${trigger.name}#constant`,\n targetSymbolId: `${filePath}::${conn.targetNode}#constant`,\n edgeType: 'n8n_triggers',\n metadata: { triggerType: trigger.type },\n });\n }\n }\n\n // ── Routes: all discoverable endpoints ──\n result.routes = extractRoutes(workflow);\n\n // ── Edges: sub-workflow calls ──\n const subWorkflowCalls = extractSubWorkflowCalls(workflow);\n for (const call of subWorkflowCalls) {\n result.edges!.push({\n sourceSymbolId: `${filePath}::${call.node.name}#constant`,\n edgeType: 'n8n_calls_subworkflow',\n metadata: { targetWorkflowId: call.workflowId, source: call.source },\n });\n }\n\n // ── Edges: HTTP requests ──\n const httpRequests = extractHttpRequests(workflow);\n for (const req of httpRequests) {\n result.edges!.push({\n sourceSymbolId: `${filePath}::${req.node.name}#constant`,\n edgeType: 'n8n_http_request',\n metadata: {\n url: req.url,\n method: req.method,\n ...(req.authentication ? { authentication: req.authentication } : {}),\n },\n });\n }\n\n // ── Edges: credential references (full detail) ──\n const credUsages = extractCredentialUsages(workflow);\n for (const usage of credUsages) {\n result.edges!.push({\n sourceSymbolId: `${filePath}::${usage.node.name}#constant`,\n edgeType: 'n8n_uses_credential',\n metadata: {\n credentialType: usage.credentialType,\n credentialId: usage.credentialId,\n credentialName: usage.credentialName,\n },\n });\n }\n\n // ── Edges: expression-based data dependencies ──\n const exprDeps = extractAllExpressionDeps(workflow);\n for (const [nodeName, deps] of exprDeps) {\n for (const dep of deps) {\n if (!nodeNameSet.has(dep)) continue;\n result.edges!.push({\n sourceSymbolId: `${filePath}::${dep}#constant`,\n targetSymbolId: `${filePath}::${nodeName}#constant`,\n edgeType: 'n8n_expression_dep',\n metadata: { referencedNode: dep },\n });\n }\n }\n\n // ── Edges: workflow-level error workflow reference ──\n if (workflow.settings?.errorWorkflow) {\n result.edges!.push({\n edgeType: 'n8n_error_workflow',\n metadata: {\n sourceWorkflow: workflow.name ?? filePath,\n targetWorkflowId: workflow.settings.errorWorkflow,\n },\n });\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n const edges: RawEdge[] = [];\n\n const allFiles = ctx.getAllFiles();\n const workflowFiles = allFiles.filter((f) => f.path.endsWith('.json'));\n\n // Build maps for cross-file resolution\n const workflowByName = new Map<string, { fileId: number; path: string }>();\n const workflowById = new Map<string, { fileId: number; path: string }>();\n const credentialUsers = new Map<string, Array<{ fileId: number; path: string; nodeName: string }>>();\n\n for (const file of workflowFiles) {\n const content = ctx.readFile(file.path);\n if (!content) continue;\n const wf = parseN8nWorkflow(Buffer.from(content));\n if (!wf) continue;\n\n if (wf.name) workflowByName.set(wf.name, { fileId: file.id, path: file.path });\n if (wf.id) workflowById.set(wf.id, { fileId: file.id, path: file.path });\n\n // Track credential usage across workflows\n const creds = extractCredentialUsages(wf);\n for (const cred of creds) {\n if (!cred.credentialId) continue;\n const key = `${cred.credentialType}:${cred.credentialId}`;\n if (!credentialUsers.has(key)) credentialUsers.set(key, []);\n credentialUsers.get(key)!.push({ fileId: file.id, path: file.path, nodeName: cred.node.name });\n }\n }\n\n // Resolve sub-workflow + error-workflow edges\n for (const file of workflowFiles) {\n const content = ctx.readFile(file.path);\n if (!content) continue;\n const wf = parseN8nWorkflow(Buffer.from(content));\n if (!wf) continue;\n\n // Sub-workflow resolution\n const calls = extractSubWorkflowCalls(wf);\n for (const call of calls) {\n const target = workflowByName.get(call.workflowId) ?? workflowById.get(call.workflowId);\n if (!target) continue;\n\n const symbols = ctx.getSymbolsByFile(target.fileId);\n if (symbols.length > 0) {\n edges.push({\n sourceSymbolId: `${file.path}::${call.node.name}#constant`,\n targetSymbolId: symbols[0].symbolId,\n edgeType: 'n8n_calls_subworkflow',\n resolved: true,\n metadata: {\n targetWorkflowId: call.workflowId,\n targetFile: target.path,\n source: call.source,\n },\n });\n }\n }\n\n // Error workflow resolution\n if (wf.settings?.errorWorkflow) {\n const target = workflowById.get(wf.settings.errorWorkflow)\n ?? workflowByName.get(wf.settings.errorWorkflow);\n if (target) {\n const symbols = ctx.getSymbolsByFile(target.fileId);\n if (symbols.length > 0) {\n edges.push({\n sourceSymbolId: `${file.path}::${wf.nodes[0]?.name}#constant`,\n targetSymbolId: symbols[0].symbolId,\n edgeType: 'n8n_error_workflow',\n resolved: true,\n metadata: {\n sourceWorkflow: wf.name ?? file.path,\n targetWorkflowId: wf.settings.errorWorkflow,\n targetFile: target.path,\n },\n });\n }\n }\n }\n }\n\n return ok(edges);\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────\n\nfunction findNodeByteOffset(source: string, nodeName: string): number {\n const escaped = nodeName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const re = new RegExp(`\"name\"\\\\s*:\\\\s*\"${escaped}\"`);\n const m = re.exec(source);\n return m ? m.index : -1;\n}\n","/**\n * DataFetchingPlugin — detects React Query (TanStack Query) and SWR projects,\n * extracts useQuery/useMutation/useSWR hooks that reference API endpoints.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\n/**\n * Match useQuery({ queryKey: [...], queryFn: () => fetch('...') })\n * Match useQuery(['key'], () => fetch('...'))\n * Match useMutation({ mutationFn: ... fetch('...') })\n */\nconst USE_QUERY_OBJECT_RE =\n /\\b(useQuery|useInfiniteQuery)\\s*\\(\\s*\\{[^}]*?queryFn\\s*:\\s*[^}]*?fetch\\s*\\(\\s*[`'\"](\\/[^'\"`$]*?)['\"`]/g;\n\nconst USE_QUERY_ARRAY_RE =\n /\\b(useQuery|useInfiniteQuery)\\s*\\(\\s*\\[[^\\]]*\\]\\s*,\\s*(?:\\([^)]*\\)\\s*=>|function\\s*\\([^)]*\\)\\s*\\{)[^)]*?fetch\\s*\\(\\s*[`'\"](\\/[^'\"`$]*?)['\"`]/g;\n\nconst USE_MUTATION_RE =\n /\\b(useMutation)\\s*\\(\\s*\\{[^}]*?mutationFn\\s*:\\s*[^}]*?fetch\\s*\\(\\s*[`'\"](\\/[^'\"`$]*?)['\"`][^)]*?(?:method\\s*:\\s*['\"`](\\w+)['\"`])?/g;\n\n/**\n * Match useSWR('/api/...', fetcher)\n * Match useSWR(() => `/api/...`, fetcher)\n */\nconst USE_SWR_STRING_RE =\n /\\buseSWR\\s*\\(\\s*['\"`](\\/[^'\"`$]*?)['\"`]/g;\n\nconst USE_SWR_FUNCTION_RE =\n /\\buseSWR\\s*\\(\\s*\\(\\s*\\)\\s*=>\\s*[`'\"](\\/[^'\"`$]*?)['\"`]/g;\n\n/**\n * Template literal fetch patterns with interpolation.\n * e.g., fetch(`/api/users/${id}`) → '/api/users/:param'\n */\nconst FETCH_TEMPLATE_RE =\n /fetch\\s*\\(\\s*`(\\/[^`]*?)\\$\\{[^}]+\\}([^`]*?)`/g;\n\nexport interface DataFetchingHook {\n hook: string;\n endpoint: string | null;\n method: string;\n}\n\n/** Normalize template literal endpoints: replace ${...} with :param */\nfunction normalizeEndpoint(raw: string): string {\n return raw.replace(/\\$\\{[^}]+\\}/g, ':param');\n}\n\n/** Extract data fetching hooks (useQuery, useMutation, useSWR) from source code. */\nexport function extractDataFetchingHooks(source: string): DataFetchingHook[] {\n const hooks: DataFetchingHook[] = [];\n const seen = new Set<string>();\n\n function add(hook: string, endpoint: string | null, method: string) {\n const key = `${hook}:${endpoint}:${method}`;\n if (!seen.has(key)) {\n seen.add(key);\n hooks.push({ hook, endpoint, method });\n }\n }\n\n // useQuery with object syntax\n let match: RegExpExecArray | null;\n const queryObjRe = new RegExp(USE_QUERY_OBJECT_RE.source, 'g');\n while ((match = queryObjRe.exec(source)) !== null) {\n add(match[1], match[2], 'FETCH');\n }\n\n // useQuery with array key syntax\n const queryArrRe = new RegExp(USE_QUERY_ARRAY_RE.source, 'g');\n while ((match = queryArrRe.exec(source)) !== null) {\n add(match[1], match[2], 'FETCH');\n }\n\n // useMutation\n const mutationRe = new RegExp(USE_MUTATION_RE.source, 'g');\n while ((match = mutationRe.exec(source)) !== null) {\n const method = match[3]?.toUpperCase() || 'POST';\n add(match[1], match[2], method);\n }\n\n // useSWR with string key\n const swrStringRe = new RegExp(USE_SWR_STRING_RE.source, 'g');\n while ((match = swrStringRe.exec(source)) !== null) {\n add('useSWR', match[1], 'FETCH');\n }\n\n // useSWR with arrow function key\n const swrFuncRe = new RegExp(USE_SWR_FUNCTION_RE.source, 'g');\n while ((match = swrFuncRe.exec(source)) !== null) {\n add('useSWR', match[1], 'FETCH');\n }\n\n // Template literal fetch with interpolation (any useQuery/useSWR context)\n const templateRe = new RegExp(FETCH_TEMPLATE_RE.source, 'g');\n while ((match = templateRe.exec(source)) !== null) {\n const endpoint = normalizeEndpoint(match[1] + '${x}' + match[2]);\n // Determine context: is this inside useQuery, useMutation, or useSWR?\n const before = source.slice(Math.max(0, match.index - 200), match.index);\n let hook = 'fetch';\n if (/useSWR\\s*\\(/.test(before)) hook = 'useSWR';\n else if (/useMutation\\s*\\(/.test(before)) hook = 'useMutation';\n else if (/useQuery\\s*\\(/.test(before)) hook = 'useQuery';\n else if (/useInfiniteQuery\\s*\\(/.test(before)) hook = 'useInfiniteQuery';\n add(hook, endpoint, 'FETCH');\n }\n\n return hooks;\n}\n\nexport class DataFetchingPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'data-fetching',\n version: '1.0.0',\n priority: 30,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if ('@tanstack/react-query' in deps || 'swr' in deps) return true;\n }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n return '@tanstack/react-query' in deps || 'swr' in deps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'fetches_endpoint', category: 'data-fetching', description: 'useQuery/useSWR call referencing an API endpoint' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (!['typescript', 'javascript'].includes(language)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = { status: 'ok', symbols: [], routes: [], edges: [] };\n\n const hooks = extractDataFetchingHooks(source);\n if (hooks.length > 0) {\n result.frameworkRole = 'data_fetching';\n for (const hook of hooks) {\n if (hook.endpoint) {\n result.routes!.push({\n method: hook.method,\n uri: hook.endpoint,\n });\n }\n }\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n","/**\n * ZodPlugin — detects Zod schema library usage and extracts schema definitions\n * with field types.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\n/**\n * Match: const schemaName = z.object({ ... })\n * Also matches export const, export default, let, var\n */\nconst ZOD_OBJECT_RE =\n /(?:export\\s+(?:default\\s+)?)?(?:const|let|var)\\s+(\\w+)\\s*=\\s*z\\.object\\s*\\(\\s*\\{([^]*?)\\}\\s*\\)/g;\n\n/**\n * Match individual fields inside z.object({ ... })\n * e.g., name: z.string(), age: z.number().optional()\n */\nconst ZOD_FIELD_RE =\n /(\\w+)\\s*:\\s*z\\.(\\w+)\\s*\\(([^)]*)\\)([.\\w()]*)/g;\n\n/**\n * Match type inference: type X = z.infer<typeof schemaName>\n */\nconst ZOD_INFER_RE =\n /type\\s+(\\w+)\\s*=\\s*z\\.infer\\s*<\\s*typeof\\s+(\\w+)\\s*>/g;\n\nexport interface ZodField {\n name: string;\n type: string;\n}\n\nexport interface ZodSchema {\n name: string;\n fields: ZodField[];\n}\n\nexport interface ZodInference {\n typeName: string;\n schemaName: string;\n}\n\n/** Map a Zod method chain to a human-readable type string. */\nfunction resolveFieldType(baseType: string, chain: string): string {\n let type = baseType;\n // Handle z.array(z.string()) etc.\n if (baseType === 'array') type = 'array';\n if (baseType === 'enum') type = 'enum';\n // Check modifiers\n if (chain.includes('.optional()')) type += '?';\n if (chain.includes('.nullable()')) type += ' | null';\n return type;\n}\n\n/** Extract field definitions from the inner body of a z.object({ ... }). */\nfunction extractFieldsFromBody(body: string): ZodField[] {\n const fields: ZodField[] = [];\n const re = new RegExp(ZOD_FIELD_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(body)) !== null) {\n const fieldName = match[1];\n const baseType = match[2];\n const chain = match[4] || '';\n fields.push({\n name: fieldName,\n type: resolveFieldType(baseType, chain),\n });\n }\n return fields;\n}\n\n/** Extract Zod schema definitions from source code. */\nexport function extractZodSchemas(source: string): ZodSchema[] {\n const schemas: ZodSchema[] = [];\n const re = new RegExp(ZOD_OBJECT_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n const name = match[1];\n const body = match[2];\n const fields = extractFieldsFromBody(body);\n schemas.push({ name, fields });\n }\n return schemas;\n}\n\n/** Extract z.infer type relationships from source code. */\nexport function extractZodInferences(source: string): ZodInference[] {\n const inferences: ZodInference[] = [];\n const re = new RegExp(ZOD_INFER_RE.source, 'g');\n let match: RegExpExecArray | null;\n while ((match = re.exec(source)) !== null) {\n inferences.push({\n typeName: match[1],\n schemaName: match[2],\n });\n }\n return inferences;\n}\n\nexport class ZodPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'zod',\n version: '1.0.0',\n priority: 30,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n if ('zod' in deps) return true;\n }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n return 'zod' in deps;\n } catch {\n return false;\n }\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'zod_schema', category: 'zod', description: 'Zod schema definition' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (!['typescript', 'javascript'].includes(language)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const result: FileParseResult = { status: 'ok', symbols: [], routes: [], edges: [] };\n\n const schemas = extractZodSchemas(source);\n if (schemas.length > 0) {\n result.frameworkRole = 'zod_schema';\n for (const schema of schemas) {\n result.routes!.push({\n method: 'SCHEMA',\n uri: `zod:${schema.name}`,\n metadata: { fields: schema.fields },\n });\n }\n }\n\n return ok(result);\n }\n\n resolveEdges(ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n","/**\n * TestingPlugin -- detects test frameworks (Playwright, Cypress, Jest, Vitest, Mocha)\n * and extracts test-to-code relationships: tested routes, tested components, and test names.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ok, type TraceMcpResult } from '../../../../errors.js';\nimport type {\n FrameworkPlugin,\n PluginManifest,\n ProjectContext,\n FileParseResult,\n RawEdge,\n ResolveContext,\n} from '../../../../plugin-api/types.js';\n\n// --- Regex patterns ---\n\n// Route visits: page.goto('/path'), cy.visit('/path')\nconst PAGE_GOTO_RE = /page\\.goto\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\nconst CY_VISIT_RE = /cy\\.visit\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n\n// API requests: request.get('/api/...'), request.post('/api/...'), request.put, request.delete, request.patch\nconst REQUEST_METHOD_RE = /request\\s*\\.\\s*(get|post|put|delete|patch)\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n\n// cy.request('METHOD', '/path') or cy.request('/path')\nconst CY_REQUEST_METHOD_RE = /cy\\.request\\s*\\(\\s*['\"`](GET|POST|PUT|DELETE|PATCH)['\"`]\\s*,\\s*['\"`]([^'\"`]+)['\"`]/g;\nconst CY_REQUEST_SIMPLE_RE = /cy\\.request\\s*\\(\\s*['\"`](\\/[^'\"`]+)['\"`]\\s*\\)/g;\n\n// fetch('/api/...')\nconst FETCH_RE = /fetch\\s*\\(\\s*['\"`](\\/[^'\"`]+)['\"`]/g;\n\n// Component rendering: render(<Foo />), mount(Foo), cy.mount(<Bar />)\nconst RENDER_JSX_RE = /render\\s*\\(\\s*<\\s*([A-Z][A-Za-z0-9]*)/g;\nconst MOUNT_RE = /mount\\s*\\(\\s*([A-Z][A-Za-z0-9]*)/g;\nconst CY_MOUNT_RE = /cy\\.mount\\s*\\(\\s*<\\s*([A-Z][A-Za-z0-9]*)/g;\n\n// Test names: test('name', ...), it('name', ...), describe('name', ...)\nconst TEST_NAME_RE = /(?:^|[;\\s])test\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\nconst IT_NAME_RE = /(?:^|[;\\s])it\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\nconst DESCRIBE_NAME_RE = /(?:^|[;\\s])describe\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\nconst TEST_DESCRIBE_RE = /test\\.describe\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n\n// Framework detection via imports\nconst PLAYWRIGHT_IMPORT_RE = /from\\s+['\"`]@playwright\\/test['\"`]/;\nconst CYPRESS_GLOBAL_RE = /\\bcy\\s*\\.\\s*(?:visit|request|mount|get|contains|intercept)\\b/;\nconst VITEST_IMPORT_RE = /from\\s+['\"`]vitest['\"`]/;\nconst JEST_IMPORT_RE = /from\\s+['\"`]@jest\\b/;\nconst JEST_GLOBALS_RE = /from\\s+['\"`]@jest\\/globals['\"`]/;\nconst MOCHA_IMPORT_RE = /from\\s+['\"`]mocha['\"`]/;\nconst MOCHA_REQUIRE_RE = /require\\s*\\(\\s*['\"`]mocha['\"`]\\s*\\)/;\n\n// E2E markers\nconst PLAYWRIGHT_E2E_RE = /page\\s*\\.\\s*(?:goto|click|fill|locator|getByRole|getByText)\\b/;\nconst CY_E2E_RE = /cy\\s*\\.\\s*(?:get|contains|intercept|wait)\\b/;\n\n/** Detect which test framework a source file uses. */\nexport function detectTestFramework(\n source: string,\n _filePath: string,\n): 'playwright' | 'cypress' | 'jest' | 'vitest' | 'mocha' | null {\n if (PLAYWRIGHT_IMPORT_RE.test(source)) return 'playwright';\n if (CYPRESS_GLOBAL_RE.test(source)) return 'cypress';\n if (VITEST_IMPORT_RE.test(source)) return 'vitest';\n if (JEST_IMPORT_RE.test(source) || JEST_GLOBALS_RE.test(source)) return 'jest';\n if (MOCHA_IMPORT_RE.test(source) || MOCHA_REQUIRE_RE.test(source)) return 'mocha';\n return null;\n}\n\n/** Extract routes tested by navigation or API calls. */\nexport function extractTestedRoutes(source: string): { path: string; method?: string }[] {\n const routes: { path: string; method?: string }[] = [];\n const seen = new Set<string>();\n\n function add(p: string, method?: string) {\n const key = `${method ?? ''}:${p}`;\n if (!seen.has(key)) {\n seen.add(key);\n routes.push({ path: p, method });\n }\n }\n\n // page.goto\n let m: RegExpExecArray | null;\n const gotoRe = new RegExp(PAGE_GOTO_RE.source, 'g');\n while ((m = gotoRe.exec(source)) !== null) add(m[1], 'GET');\n\n // cy.visit\n const visitRe = new RegExp(CY_VISIT_RE.source, 'g');\n while ((m = visitRe.exec(source)) !== null) add(m[1], 'GET');\n\n // request.get/post/...\n const reqRe = new RegExp(REQUEST_METHOD_RE.source, 'g');\n while ((m = reqRe.exec(source)) !== null) add(m[2], m[1].toUpperCase());\n\n // cy.request('METHOD', '/path')\n const cyReqMethodRe = new RegExp(CY_REQUEST_METHOD_RE.source, 'g');\n while ((m = cyReqMethodRe.exec(source)) !== null) add(m[2], m[1].toUpperCase());\n\n // cy.request('/path')\n const cyReqSimpleRe = new RegExp(CY_REQUEST_SIMPLE_RE.source, 'g');\n while ((m = cyReqSimpleRe.exec(source)) !== null) add(m[1]);\n\n // fetch('/api/...')\n const fetchRe = new RegExp(FETCH_RE.source, 'g');\n while ((m = fetchRe.exec(source)) !== null) add(m[1]);\n\n return routes;\n}\n\n/** Extract component names tested via render/mount. */\nexport function extractTestedComponents(source: string): string[] {\n const components: string[] = [];\n const seen = new Set<string>();\n\n function add(name: string) {\n if (!seen.has(name)) {\n seen.add(name);\n components.push(name);\n }\n }\n\n let m: RegExpExecArray | null;\n\n const renderRe = new RegExp(RENDER_JSX_RE.source, 'g');\n while ((m = renderRe.exec(source)) !== null) add(m[1]);\n\n const mountRe = new RegExp(MOUNT_RE.source, 'g');\n while ((m = mountRe.exec(source)) !== null) add(m[1]);\n\n const cyMountRe = new RegExp(CY_MOUNT_RE.source, 'g');\n while ((m = cyMountRe.exec(source)) !== null) add(m[1]);\n\n return components;\n}\n\n/** Extract test and describe block names. */\nexport function extractTestNames(source: string): { name: string; type: 'test' | 'describe' }[] {\n const names: { name: string; type: 'test' | 'describe' }[] = [];\n\n let m: RegExpExecArray | null;\n\n const testRe = new RegExp(TEST_NAME_RE.source, 'g');\n while ((m = testRe.exec(source)) !== null) names.push({ name: m[1], type: 'test' });\n\n const itRe = new RegExp(IT_NAME_RE.source, 'g');\n while ((m = itRe.exec(source)) !== null) names.push({ name: m[1], type: 'test' });\n\n const describeRe = new RegExp(DESCRIBE_NAME_RE.source, 'g');\n while ((m = describeRe.exec(source)) !== null) names.push({ name: m[1], type: 'describe' });\n\n const testDescRe = new RegExp(TEST_DESCRIBE_RE.source, 'g');\n while ((m = testDescRe.exec(source)) !== null) names.push({ name: m[1], type: 'describe' });\n\n return names;\n}\n\nconst TESTING_DEPS = ['@playwright/test', 'cypress', 'jest', 'vitest', 'mocha'];\n\nexport class TestingPlugin implements FrameworkPlugin {\n manifest: PluginManifest = {\n name: 'testing',\n version: '1.0.0',\n priority: 50,\n dependencies: [],\n };\n\n detect(ctx: ProjectContext): boolean {\n if (ctx.packageJson) {\n const deps = {\n ...(ctx.packageJson.dependencies as Record<string, string> | undefined),\n ...(ctx.packageJson.devDependencies as Record<string, string> | undefined),\n };\n for (const dep of TESTING_DEPS) {\n if (dep in deps) return true;\n }\n }\n\n try {\n const pkgPath = path.join(ctx.rootPath, 'package.json');\n const content = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(content);\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n for (const dep of TESTING_DEPS) {\n if (dep in deps) return true;\n }\n } catch {\n // no package.json or parse error\n }\n\n return false;\n }\n\n registerSchema() {\n return {\n edgeTypes: [\n { name: 'test_covers_route', category: 'testing', description: 'Test file visits/requests an API route' },\n { name: 'test_covers_component', category: 'testing', description: 'Test file mounts/renders a component' },\n { name: 'test_imports_module', category: 'testing', description: 'Test file imports the module under test' },\n ],\n };\n }\n\n extractNodes(\n filePath: string,\n content: Buffer,\n language: string,\n ): TraceMcpResult<FileParseResult> {\n if (!['typescript', 'javascript'].includes(language)) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const source = content.toString('utf-8');\n const framework = detectTestFramework(source, filePath);\n if (!framework) {\n return ok({ status: 'ok', symbols: [] });\n }\n\n const result: FileParseResult = { status: 'ok', symbols: [], routes: [], edges: [] };\n\n // Determine framework role\n const isE2e =\n PLAYWRIGHT_E2E_RE.test(source) ||\n CY_E2E_RE.test(source) ||\n PAGE_GOTO_RE.test(source) ||\n CY_VISIT_RE.test(source);\n\n if (framework === 'playwright') {\n result.frameworkRole = isE2e ? 'e2e_test' : 'playwright_test';\n } else if (framework === 'cypress') {\n result.frameworkRole = isE2e ? 'e2e_test' : 'cypress_test';\n } else {\n result.frameworkRole = 'unit_test';\n }\n\n // Extract tested routes\n const routes = extractTestedRoutes(source);\n for (const route of routes) {\n result.routes!.push({\n method: 'TEST_ROUTE',\n uri: route.path,\n metadata: route.method ? { httpMethod: route.method } : undefined,\n });\n }\n\n // Extract tested components\n const components = extractTestedComponents(source);\n for (const name of components) {\n result.routes!.push({\n method: 'TEST_COMPONENT',\n uri: name,\n });\n }\n\n // Extract test names\n const testNames = extractTestNames(source);\n for (const t of testNames) {\n result.routes!.push({\n method: 'TEST',\n uri: t.name,\n metadata: { testType: t.type },\n });\n }\n\n return ok(result);\n }\n\n resolveEdges(_ctx: ResolveContext): TraceMcpResult<RawEdge[]> {\n return ok([]);\n }\n}\n","import * as parcelWatcher from '@parcel/watcher';\nimport path from 'node:path';\nimport type { TraceMcpConfig } from '../config.js';\nimport { logger } from '../logger.js';\n\nconst IGNORE_DIRS = [\n 'vendor', 'node_modules', '.git', 'storage',\n 'bootstrap/cache', '.nuxt', '.next', 'dist', 'build', '.idea',\n];\n\n/** Debounce window in ms — coalesces rapid saves from editors. */\nexport const DEFAULT_DEBOUNCE_MS = 300;\n\nexport class FileWatcher {\n private subscription: parcelWatcher.AsyncSubscription | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private pendingPaths: Set<string> = new Set();\n\n constructor(\n private readonly _setTimeout: typeof setTimeout = setTimeout,\n private readonly _clearTimeout: typeof clearTimeout = clearTimeout,\n ) {}\n\n async start(\n rootPath: string,\n config: TraceMcpConfig,\n onChanges: (paths: string[]) => Promise<void>,\n debounceMs = DEFAULT_DEBOUNCE_MS,\n onDeletes?: (paths: string[]) => Promise<void>,\n ): Promise<void> {\n const ignoreDirs = IGNORE_DIRS.map((d) => path.join(rootPath, d));\n\n this.subscription = await parcelWatcher.subscribe(\n rootPath,\n async (err, events) => {\n if (err) {\n logger.error({ error: err }, 'Watcher error');\n return;\n }\n\n const notIgnored = (p: string) => !ignoreDirs.some((d) => p.startsWith(d));\n\n const changed = events\n .filter((e) => e.type === 'create' || e.type === 'update')\n .map((e) => e.path)\n .filter(notIgnored);\n\n const deleted = events\n .filter((e) => e.type === 'delete')\n .map((e) => e.path)\n .filter(notIgnored);\n\n if (deleted.length > 0 && onDeletes) {\n logger.debug({ count: deleted.length }, 'File deletions detected');\n await onDeletes(deleted);\n }\n\n if (changed.length === 0) return;\n\n // Accumulate paths and debounce — multiple rapid saves collapse into one call\n for (const p of changed) this.pendingPaths.add(p);\n\n if (this.debounceTimer) this._clearTimeout(this.debounceTimer);\n this.debounceTimer = this._setTimeout(async () => {\n const paths = Array.from(this.pendingPaths);\n this.pendingPaths.clear();\n this.debounceTimer = null;\n logger.debug({ count: paths.length }, 'File changes detected');\n await onChanges(paths);\n }, debounceMs);\n },\n {\n ignore: ignoreDirs,\n },\n );\n\n logger.info({ rootPath }, 'File watcher started');\n }\n\n async stop(): Promise<void> {\n if (this.debounceTimer) {\n this._clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n this.pendingPaths.clear();\n }\n if (this.subscription) {\n await this.subscription.unsubscribe();\n this.subscription = null;\n logger.info('File watcher stopped');\n }\n }\n}\n"],"mappings":"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","names":["path","fs","path","z","languageRows","path","ok","err","err","path","ok","path","path","fs","path","fg","fs","path","path","path","fs","path","path","fs","path","path","ok","fs","fg","fs","path","z","path","z","fs","path","fs","path","extractDecorators","fs","path","fs","path","path","fs","fs","path","ok","err","ok","err","ok","err","resolveTargetName","path","ok","err","path","j","z","ok","err","require","ok","err","createRequire","ok","err","makeSymbolId","extractSignature","require","createRequire","Parser","getParser","ok","err","makeSymbolId","createRequire","ok","err","require","createRequire","Parser","TsGrammar","tsParser","getParser","makeSymbolId","ok","err","createRequire","ok","err","makeSymbolId","makeFqn","extractSignature","extractImportEdges","getNodeName","extractClassMethods","isAsync","require","createRequire","Parser","parserInstance","getParser","extractImportEdges","ok","err","getNodeName","makeFqn","makeSymbolId","extractSignature","extractClassMethods","createRequire","ok","err","makeSymbolId","makeFqn","extractSignature","getNodeName","extractImportEdges","extractClassMethods","makeSymbolId","require","createRequire","Parser","parserInstance","getParser","extractImportEdges","ok","err","getNodeName","makeSymbolId","makeFqn","extractSignature","extractClassMethods","ok","err","ok","err","createRequire","ok","err","makeSymbolId","makeFqn","extractSignature","getNodeName","getNodeName","makeSymbolId","makeFqn","extractSignature","extractAttributes","extractImportEdges","require","createRequire","Parser","parserInstance","getParser","extractImportEdges","ok","err","getNodeName","makeSymbolId","makeFqn","extractSignature","extractAttributes","createRequire","ok","err","makeSymbolId","makeFqn","extractPackageName","extractSignature","getNodeName","extractImportEdges","require","createRequire","Parser","parserInstance","getParser","extractPackageName","extractImportEdges","ok","err","getNodeName","makeSymbolId","makeFqn","extractSignature","fs","path","ok","HTTP_METHODS","buildUseMap","extractNamespace","buildUseMap","buildUseMap","resolveClass","buildUseMap","resolveClass","buildUseMap","detectVersion","resolveClass","buildUseMap","resolveClass","detectVersion","NAMESPACE_RE","USE_STMT_RE","buildUseMap","buildUseMap","USE_STMT_RE","resolveClass","NAMESPACE_RE","CLASS_NAME_RE","USE_STMT_RE","EXTENDS_RESOURCE_RE","EXTENDS_RESOURCE_RE","buildUseMap","NAMESPACE_RE","CLASS_NAME_RE","resolveClass","buildUseMap","USE_STMT_RE","resolveClass","NAMESPACE_RE","CLASS_NAME_RE","USE_STMT_RE","buildUseMap","resolveClass","buildUseMap","USE_STMT_RE","resolveClass","NAMESPACE_RE","CLASS_NAME_RE","USE_STMT_RE","buildUseMap","buildUseMap","USE_STMT_RE","resolveClass","shortName","lineAt","lineAt","path","fs","ok","rm","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","ok","path","fs","ok","extractMethods","fs","path","ok","extractScopes","extractScopes","m","fs","path","ok","fs","path","ok","fs","ok","j","ok","ok","createRequire","fs","path","ok","err","require","createRequire","Parser","PythonGrammar","parserInstance","getParser","fs","path","ok","err","createRequire","fs","path","ok","err","require","createRequire","Parser","PythonGrammar","parserInstance","getParser","hasPythonDep","fs","path","findClassDefinitions","getSuperclasses","getClassName","getClassBody","findAssignment","findNestedClass","shortName","ok","err","createRequire","fs","path","ok","err","require","createRequire","Parser","PythonGrammar","parserInstance","getParser","hasPythonDep","fs","path","stripQuotes","stripQuotes","hasPythonDep","ok","getParser","err","createRequire","fs","path","ok","err","require","createRequire","Parser","PythonGrammar","HTTP_METHODS","hasPythonDep","path","fs","ok","err","createRequire","fs","path","ok","err","require","createRequire","Parser","PythonGrammar","hasPythonDep","path","fs","ok","err","createRequire","fs","path","ok","err","require","createRequire","Parser","PythonGrammar","hasPythonDep","path","fs","ok","err","ok","path","ok","fs","path","ok","RELATIONSHIP_FIELDS","extractAssociations","j","j","path","fs","ok","createRequire","ok","err","require","createRequire","Parser","TsGrammar","tsParser","tsxParser","getParser","ok","err","fs","path","path","fs","fs","path","path","fs","fs","path","ROUTE_RE","ROUTE_RE","path","fs","fs","path","NAMESPACE_RE","path","fs","ok","extractDispatches","extractBraceBody","fs","path","extractRoutes","fs","path","extractRoutes","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","path","path","err","path","fs","err"]}
|