feat: add semantic graph design for static code analysis

- Introduced a comprehensive design document for a Code Semantic Graph aimed at enhancing static analysis capabilities.
- Defined the architecture, core components, and implementation steps for analyzing function calls, data flow, and dependencies.
- Included detailed specifications for nodes and edges in the graph, along with database schema for storage.
- Outlined phases for implementation, technical challenges, success metrics, and application scenarios.
This commit is contained in:
catlog22
2025-12-15 09:47:18 +08:00
parent d91477ad80
commit 3ffb907a6f
17 changed files with 4557 additions and 261 deletions

View File

@@ -0,0 +1,269 @@
// @ts-nocheck
/**
* MCP Templates Database Module
* Stores MCP server configurations as reusable templates
*/
import Database from 'better-sqlite3';
import { existsSync, mkdirSync } from 'fs';
import { join, dirname } from 'path';
import { homedir } from 'os';
// Database path
const DB_DIR = join(homedir(), '.ccw');
const DB_PATH = join(DB_DIR, 'mcp-templates.db');
// Ensure database directory exists
if (!existsSync(DB_DIR)) {
mkdirSync(DB_DIR, { recursive: true });
}
// Initialize database connection
let db: Database.Database | null = null;
/**
* Get or create database connection
*/
function getDb(): Database.Database {
if (!db) {
db = new Database(DB_PATH);
initDatabase();
}
return db;
}
/**
* Initialize database schema
*/
function initDatabase() {
const db = getDb();
// Create templates table
db.exec(`
CREATE TABLE IF NOT EXISTS mcp_templates (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
description TEXT,
server_config TEXT NOT NULL,
tags TEXT,
category TEXT,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
)
`);
// Create index on name for fast lookups
db.exec(`
CREATE INDEX IF NOT EXISTS idx_mcp_templates_name
ON mcp_templates(name)
`);
// Create index on category for filtering
db.exec(`
CREATE INDEX IF NOT EXISTS idx_mcp_templates_category
ON mcp_templates(category)
`);
}
export interface McpTemplate {
id?: number;
name: string;
description?: string;
serverConfig: {
command: string;
args?: string[];
env?: Record<string, string>;
};
tags?: string[];
category?: string;
createdAt?: number;
updatedAt?: number;
}
/**
* Save MCP template to database
*/
export function saveTemplate(template: McpTemplate): { success: boolean; id?: number; error?: string } {
try {
const db = getDb();
const now = Date.now();
const stmt = db.prepare(`
INSERT INTO mcp_templates (name, description, server_config, tags, category, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(name) DO UPDATE SET
description = excluded.description,
server_config = excluded.server_config,
tags = excluded.tags,
category = excluded.category,
updated_at = excluded.updated_at
`);
const result = stmt.run(
template.name,
template.description || null,
JSON.stringify(template.serverConfig),
template.tags ? JSON.stringify(template.tags) : null,
template.category || null,
template.createdAt || now,
now
);
return {
success: true,
id: result.lastInsertRowid as number
};
} catch (error: unknown) {
console.error('Error saving MCP template:', error);
return {
success: false,
error: (error as Error).message
};
}
}
/**
* Get all MCP templates
*/
export function getAllTemplates(): McpTemplate[] {
try {
const db = getDb();
const rows = db.prepare('SELECT * FROM mcp_templates ORDER BY name').all();
return rows.map((row: any) => ({
id: row.id,
name: row.name,
description: row.description,
serverConfig: JSON.parse(row.server_config),
tags: row.tags ? JSON.parse(row.tags) : [],
category: row.category,
createdAt: row.created_at,
updatedAt: row.updated_at
}));
} catch (error: unknown) {
console.error('Error getting MCP templates:', error);
return [];
}
}
/**
* Get template by name
*/
export function getTemplateByName(name: string): McpTemplate | null {
try {
const db = getDb();
const row = db.prepare('SELECT * FROM mcp_templates WHERE name = ?').get(name);
if (!row) return null;
return {
id: (row as any).id,
name: (row as any).name,
description: (row as any).description,
serverConfig: JSON.parse((row as any).server_config),
tags: (row as any).tags ? JSON.parse((row as any).tags) : [],
category: (row as any).category,
createdAt: (row as any).created_at,
updatedAt: (row as any).updated_at
};
} catch (error: unknown) {
console.error('Error getting MCP template:', error);
return null;
}
}
/**
* Get templates by category
*/
export function getTemplatesByCategory(category: string): McpTemplate[] {
try {
const db = getDb();
const rows = db.prepare('SELECT * FROM mcp_templates WHERE category = ? ORDER BY name').all(category);
return rows.map((row: any) => ({
id: row.id,
name: row.name,
description: row.description,
serverConfig: JSON.parse(row.server_config),
tags: row.tags ? JSON.parse(row.tags) : [],
category: row.category,
createdAt: row.created_at,
updatedAt: row.updated_at
}));
} catch (error: unknown) {
console.error('Error getting MCP templates by category:', error);
return [];
}
}
/**
* Delete template by name
*/
export function deleteTemplate(name: string): { success: boolean; error?: string } {
try {
const db = getDb();
const result = db.prepare('DELETE FROM mcp_templates WHERE name = ?').run(name);
return {
success: result.changes > 0
};
} catch (error: unknown) {
console.error('Error deleting MCP template:', error);
return {
success: false,
error: (error as Error).message
};
}
}
/**
* Search templates by keyword
*/
export function searchTemplates(keyword: string): McpTemplate[] {
try {
const db = getDb();
const searchPattern = `%${keyword}%`;
const rows = db.prepare(`
SELECT * FROM mcp_templates
WHERE name LIKE ? OR description LIKE ? OR tags LIKE ?
ORDER BY name
`).all(searchPattern, searchPattern, searchPattern);
return rows.map((row: any) => ({
id: row.id,
name: row.name,
description: row.description,
serverConfig: JSON.parse(row.server_config),
tags: row.tags ? JSON.parse(row.tags) : [],
category: row.category,
createdAt: row.created_at,
updatedAt: row.updated_at
}));
} catch (error: unknown) {
console.error('Error searching MCP templates:', error);
return [];
}
}
/**
* Get all categories
*/
export function getAllCategories(): string[] {
try {
const db = getDb();
const rows = db.prepare('SELECT DISTINCT category FROM mcp_templates WHERE category IS NOT NULL ORDER BY category').all();
return rows.map((row: any) => row.category);
} catch (error: unknown) {
console.error('Error getting categories:', error);
return [];
}
}
/**
* Close database connection
*/
export function closeDb() {
if (db) {
db.close();
db = null;
}
}