Refactor multi-CLI planning documentation, enhance analyze-with-file skill, and implement timeout for DeepWiki API requests

- Updated SKILL.md for workflow-multi-cli-plan to streamline sections, clarify processes, and improve user decision points.
- Enhanced analyze-with-file skill to include hypothesis impact in key findings and refined recording principles for better documentation.
- Added fetchWithTimeout function to DeepWiki API calls to handle request timeouts, ensuring more robust error handling.
- Introduced new DeepWiki routes in server.ts to manage API requests effectively.
- Updated tsconfig.tsbuildinfo to reflect recent changes in the codebase structure.
This commit is contained in:
catlog22
2026-03-06 15:54:40 +08:00
parent 88149b6154
commit f2d4364c69
8 changed files with 477 additions and 639 deletions

View File

@@ -67,11 +67,29 @@ const STALE_TIME = 5 * 60 * 1000;
// Default garbage collection time: 10 minutes
const GC_TIME = 10 * 60 * 1000;
// Request timeout: 10 seconds
const REQUEST_TIMEOUT = 10 * 1000;
/**
* Fetch with timeout wrapper
*/
async function fetchWithTimeout(url: string, timeout: number = REQUEST_TIMEOUT): Promise<Response> {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { signal: controller.signal });
return response;
} finally {
clearTimeout(timeoutId);
}
}
/**
* Fetch list of documented files
*/
async function fetchDeepWikiFiles(): Promise<DeepWikiFile[]> {
const response = await fetch('/api/deepwiki/files');
const response = await fetchWithTimeout('/api/deepwiki/files');
if (!response.ok) {
throw new Error(`Failed to fetch files: ${response.statusText}`);
}
@@ -82,7 +100,7 @@ async function fetchDeepWikiFiles(): Promise<DeepWikiFile[]> {
* Fetch document by source file path
*/
async function fetchDeepWikiDoc(filePath: string): Promise<DocumentResponse> {
const response = await fetch(`/api/deepwiki/doc?path=${encodeURIComponent(filePath)}`);
const response = await fetchWithTimeout(`/api/deepwiki/doc?path=${encodeURIComponent(filePath)}`);
if (!response.ok) {
if (response.status === 404) {
return { doc: null, content: '', symbols: [] };
@@ -96,7 +114,7 @@ async function fetchDeepWikiDoc(filePath: string): Promise<DocumentResponse> {
* Fetch DeepWiki statistics
*/
async function fetchDeepWikiStats(): Promise<DeepWikiStats> {
const response = await fetch('/api/deepwiki/stats');
const response = await fetchWithTimeout('/api/deepwiki/stats');
if (!response.ok) {
throw new Error(`Failed to fetch stats: ${response.statusText}`);
}
@@ -107,7 +125,7 @@ async function fetchDeepWikiStats(): Promise<DeepWikiStats> {
* Search symbols by query
*/
async function searchDeepWikiSymbols(query: string, limit = 50): Promise<DeepWikiSymbol[]> {
const response = await fetch(`/api/deepwiki/search?q=${encodeURIComponent(query)}&limit=${limit}`);
const response = await fetchWithTimeout(`/api/deepwiki/search?q=${encodeURIComponent(query)}&limit=${limit}`);
if (!response.ok) {
throw new Error(`Failed to search symbols: ${response.statusText}`);
}

View File

@@ -578,6 +578,11 @@ export async function startServer(options: ServerOptions = {}): Promise<http.Ser
if (await handleMcpRoutes(routeContext)) return;
}
// DeepWiki routes (/api/deepwiki/*)
if (pathname.startsWith('/api/deepwiki')) {
if (await handleDeepWikiRoutes(routeContext)) return;
}
// Hooks routes (/api/hooks, /api/hook)
if (pathname.startsWith('/api/hook')) {
if (await handleHooksRoutes(routeContext)) return;

View File

@@ -250,6 +250,35 @@ export class DeepWikiService {
return [];
}
}
/**
* Get storage statistics
* @returns Statistics object with counts
*/
public getStats(): { files: number; symbols: number; docs: number; filesNeedingDocs: number; dbPath: string } {
const db = this.getConnection();
if (!db) {
return { files: 0, symbols: 0, docs: 0, filesNeedingDocs: 0, dbPath: this.dbPath };
}
try {
const files = db.prepare('SELECT COUNT(*) as count FROM deepwiki_files').get() as { count: number };
const symbols = db.prepare('SELECT COUNT(*) as count FROM deepwiki_symbols').get() as { count: number };
const docs = db.prepare('SELECT COUNT(*) as count FROM deepwiki_docs').get() as { count: number };
const filesNeedingDocs = db.prepare('SELECT COUNT(*) as count FROM deepwiki_files WHERE docs_generated = 0').get() as { count: number };
return {
files: files?.count || 0,
symbols: symbols?.count || 0,
docs: docs?.count || 0,
filesNeedingDocs: filesNeedingDocs?.count || 0,
dbPath: this.dbPath
};
} catch (error) {
console.error('[DeepWiki] Error getting stats:', error);
return { files: 0, symbols: 0, docs: 0, filesNeedingDocs: 0, dbPath: this.dbPath };
}
}
}
// Singleton instance

File diff suppressed because one or more lines are too long