@weavelogic/knowledge-graph-agent 0.10.0 → 0.10.2
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/README.md +166 -2
- package/dist/agents/base-agent.js +3 -3
- package/dist/agents/base-agent.js.map +1 -1
- package/dist/cli/commands/analyze.js +3 -3
- package/dist/cli/commands/analyze.js.map +1 -1
- package/dist/cli/commands/convert.js +1 -1
- package/dist/cli/commands/convert.js.map +1 -1
- package/dist/cli/commands/cultivate.js +8 -3
- package/dist/cli/commands/cultivate.js.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cultivation/deep-analyzer.d.ts +8 -1
- package/dist/cultivation/deep-analyzer.d.ts.map +1 -1
- package/dist/cultivation/deep-analyzer.js +36 -8
- package/dist/cultivation/deep-analyzer.js.map +1 -1
- package/dist/generators/claude-md.js +1 -1
- package/dist/generators/claude-md.js.map +1 -1
- package/dist/generators/doc-cultivator.js +2 -3
- package/dist/generators/doc-cultivator.js.map +1 -1
- package/dist/generators/doc-generator-agents.js +18 -9
- package/dist/generators/doc-generator-agents.js.map +1 -1
- package/dist/generators/docs-analyzer.d.ts +2 -2
- package/dist/generators/docs-analyzer.d.ts.map +1 -1
- package/dist/generators/docs-analyzer.js +1 -1
- package/dist/generators/docs-analyzer.js.map +1 -1
- package/dist/generators/docs-convert.d.ts +1 -1
- package/dist/generators/docs-convert.d.ts.map +1 -1
- package/dist/generators/docs-convert.js +1 -1
- package/dist/generators/docs-convert.js.map +1 -1
- package/dist/integrations/claude-flow.js +4 -4
- package/dist/integrations/claude-flow.js.map +1 -1
- package/dist/mcp/clients/mcp-client-adapter.d.ts +1 -1
- package/dist/mcp/clients/mcp-client-adapter.d.ts.map +1 -1
- package/dist/mcp/clients/mcp-client-adapter.js +1 -1
- package/dist/mcp/clients/mcp-client-adapter.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-client-adapter.js","sources":["../../../src/mcp/clients/mcp-client-adapter.ts"],"sourcesContent":["/**\n * MCP Client Adapter\n *\n * Provides real MCP tool execution via the claude-flow CLI with retry logic,\n * timeout handling, and graceful fallback to in-memory storage when CLI is unavailable.\n *\n * @module mcp/clients/mcp-client-adapter\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport {\n createLogger,\n withRetry,\n type RetryOptions,\n} from '../../utils/index.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Extended exec error type with additional properties\n */\ninterface ExecError extends Error {\n code?: string | number;\n killed?: boolean;\n stderr?: string;\n stdout?: string;\n}\nconst logger = createLogger('mcp-client-adapter');\n\n/**\n * MCP Client Configuration\n */\nexport interface McpClientConfig {\n /** Maximum number of retry attempts (default: 3) */\n maxRetries: number;\n\n /** Initial delay in milliseconds between retries (default: 1000) */\n retryDelayMs: number;\n\n /** Command execution timeout in milliseconds (default: 30000) */\n timeoutMs: number;\n\n /** Whether to fallback to in-memory storage when CLI unavailable (default: true) */\n fallbackEnabled: boolean;\n\n /** Claude-flow CLI command (default: 'npx claude-flow@alpha') */\n cliCommand: string;\n\n /** Whether to use JSON output format from CLI when available */\n useJsonOutput: boolean;\n}\n\n/**\n * Result of a memory operation\n */\nexport interface MemoryOperationResult {\n /** Whether the operation succeeded */\n success: boolean;\n\n /** Result data (if successful) */\n data?: unknown;\n\n /** Error message (if failed) */\n error?: string;\n\n /** Whether the result came from fallback storage */\n fromFallback: boolean;\n\n /** Number of attempts made */\n attempts: number;\n}\n\n/**\n * Memory entry stored in fallback\n */\ninterface FallbackEntry {\n value: string;\n ttl?: number;\n createdAt: number;\n expiresAt?: number;\n}\n\n/**\n * MCP Client Adapter\n *\n * Executes real claude-flow CLI commands with robust retry logic and fallback.\n *\n * @example\n * ```typescript\n * const adapter = new McpClientAdapter({\n * maxRetries: 3,\n * timeoutMs: 30000,\n * });\n *\n * // Store value\n * await adapter.memoryStore('myKey', 'myValue', 'myNamespace');\n *\n * // Retrieve value\n * const value = await adapter.memoryRetrieve('myKey', 'myNamespace');\n * ```\n */\nexport class McpClientAdapter {\n private config: McpClientConfig;\n private fallbackStore: Map<string, Map<string, FallbackEntry>>;\n private cliAvailable: boolean | null = null;\n private lastCliCheck: number = 0;\n private readonly CLI_CHECK_INTERVAL = 60000; // Re-check CLI availability every 60s\n\n constructor(config: Partial<McpClientConfig> = {}) {\n this.config = {\n maxRetries: config.maxRetries ?? 3,\n retryDelayMs: config.retryDelayMs ?? 1000,\n timeoutMs: config.timeoutMs ?? 30000,\n fallbackEnabled: config.fallbackEnabled ?? true,\n cliCommand: config.cliCommand ?? 'npx claude-flow@alpha',\n useJsonOutput: config.useJsonOutput ?? true,\n };\n this.fallbackStore = new Map();\n }\n\n /**\n * Store a value in memory\n *\n * @param key - Memory key\n * @param value - Value to store (will be JSON stringified if object)\n * @param namespace - Memory namespace (default: 'default')\n * @param ttl - Time to live in seconds (optional)\n * @returns Whether the operation succeeded\n */\n async memoryStore(\n key: string,\n value: string | object,\n namespace: string = 'default',\n ttl?: number\n ): Promise<boolean> {\n const stringValue = typeof value === 'string' ? value : JSON.stringify(value);\n\n const result = await this.executeWithRetry(async () => {\n const command = this.buildStoreCommand(key, stringValue, namespace, ttl);\n await this.executeCli(command);\n return true;\n });\n\n if (result.success) {\n logger.debug('Memory store succeeded via CLI', { key, namespace });\n return true;\n }\n\n // Fallback to in-memory storage\n if (this.config.fallbackEnabled) {\n this.storeFallback(key, stringValue, namespace, ttl);\n logger.warn('Memory store fell back to in-memory', { key, namespace, error: result.error });\n return true;\n }\n\n logger.error('Memory store failed', undefined, { key, namespace, error: result.error });\n return false;\n }\n\n /**\n * Retrieve a value from memory\n *\n * @param key - Memory key\n * @param namespace - Memory namespace (default: 'default')\n * @returns The stored value or null if not found\n */\n async memoryRetrieve(key: string, namespace: string = 'default'): Promise<string | null> {\n const result = await this.executeWithRetry(async () => {\n const command = this.buildQueryCommand(key, namespace);\n const output = await this.executeCli(command);\n return this.parseQueryOutput(output, key);\n });\n\n if (result.success && result.value !== undefined) {\n logger.debug('Memory retrieve succeeded via CLI', { key, namespace });\n return result.value;\n }\n\n // Fallback to in-memory storage\n if (this.config.fallbackEnabled) {\n const fallbackValue = this.retrieveFallback(key, namespace);\n if (fallbackValue !== null) {\n logger.debug('Memory retrieve fell back to in-memory', { key, namespace });\n return fallbackValue;\n }\n }\n\n logger.debug('Memory retrieve returned null', { key, namespace });\n return null;\n }\n\n /**\n * Search memory by pattern\n *\n * @param pattern - Search pattern (supports glob-like matching)\n * @param namespace - Memory namespace (default: 'default')\n * @param limit - Maximum number of results (default: 10)\n * @returns Array of matching keys\n */\n async memorySearch(\n pattern: string,\n namespace: string = 'default',\n limit: number = 10\n ): Promise<string[]> {\n const result = await this.executeWithRetry(async () => {\n const command = this.buildSearchCommand(pattern, namespace, limit);\n const output = await this.executeCli(command);\n return this.parseSearchOutput(output);\n });\n\n if (result.success && result.value) {\n logger.debug('Memory search succeeded via CLI', { pattern, namespace, count: result.value.length });\n return result.value;\n }\n\n // Fallback to in-memory search\n if (this.config.fallbackEnabled) {\n const fallbackResults = this.searchFallback(pattern, namespace, limit);\n logger.debug('Memory search fell back to in-memory', { pattern, namespace, count: fallbackResults.length });\n return fallbackResults;\n }\n\n logger.debug('Memory search returned empty', { pattern, namespace });\n return [];\n }\n\n /**\n * Delete a value from memory\n *\n * @param key - Memory key\n * @param namespace - Memory namespace (default: 'default')\n * @returns Whether the operation succeeded\n */\n async memoryDelete(key: string, namespace: string = 'default'): Promise<boolean> {\n const result = await this.executeWithRetry(async () => {\n // Use clear command with specific key pattern\n const command = this.buildDeleteCommand(key, namespace);\n await this.executeCli(command);\n return true;\n });\n\n if (result.success) {\n logger.debug('Memory delete succeeded via CLI', { key, namespace });\n }\n\n // Also delete from fallback (regardless of CLI success)\n if (this.config.fallbackEnabled) {\n this.deleteFallback(key, namespace);\n }\n\n return result.success || this.config.fallbackEnabled;\n }\n\n /**\n * List all keys in a namespace\n *\n * @param namespace - Memory namespace (default: 'default')\n * @returns Array of keys\n */\n async memoryList(namespace: string = 'default'): Promise<string[]> {\n const result = await this.executeWithRetry(async () => {\n const command = `${this.config.cliCommand} memory list --namespace \"${namespace}\"`;\n const output = await this.executeCli(command);\n return this.parseListOutput(output);\n });\n\n if (result.success && result.value) {\n logger.debug('Memory list succeeded via CLI', { namespace, count: result.value.length });\n return result.value;\n }\n\n // Fallback\n if (this.config.fallbackEnabled) {\n const fallbackKeys = this.listFallback(namespace);\n logger.debug('Memory list fell back to in-memory', { namespace, count: fallbackKeys.length });\n return fallbackKeys;\n }\n\n return [];\n }\n\n /**\n * Check if CLI is available\n */\n async isCliAvailable(): Promise<boolean> {\n const now = Date.now();\n\n // Use cached result if recent\n if (this.cliAvailable !== null && now - this.lastCliCheck < this.CLI_CHECK_INTERVAL) {\n return this.cliAvailable;\n }\n\n try {\n await this.executeCli(`${this.config.cliCommand} --version`, 5000);\n this.cliAvailable = true;\n this.lastCliCheck = now;\n return true;\n } catch {\n this.cliAvailable = false;\n this.lastCliCheck = now;\n return false;\n }\n }\n\n /**\n * Get current configuration\n */\n getConfig(): Readonly<McpClientConfig> {\n return { ...this.config };\n }\n\n /**\n * Get fallback store size for a namespace\n */\n getFallbackSize(namespace: string = 'default'): number {\n return this.fallbackStore.get(namespace)?.size ?? 0;\n }\n\n /**\n * Clear fallback store\n */\n clearFallback(namespace?: string): void {\n if (namespace) {\n this.fallbackStore.delete(namespace);\n } else {\n this.fallbackStore.clear();\n }\n }\n\n // Private methods\n\n private async executeWithRetry<T>(\n operation: () => Promise<T>\n ): Promise<{ success: boolean; value?: T; error?: string; attempts: number }> {\n const retryOptions: RetryOptions = {\n maxRetries: this.config.maxRetries,\n initialDelay: this.config.retryDelayMs,\n backoffFactor: 2,\n jitter: true,\n onRetry: (error, attempt, delay) => {\n logger.debug('Retrying MCP operation', {\n attempt,\n delay,\n error: error.message,\n });\n },\n };\n\n const result = await withRetry(operation, retryOptions);\n\n return {\n success: result.success,\n value: result.value,\n error: result.error?.message,\n attempts: result.attempts,\n };\n }\n\n private async executeCli(command: string, timeout?: number): Promise<string> {\n const effectiveTimeout = timeout ?? this.config.timeoutMs;\n\n logger.debug('Executing CLI command', { command: command.substring(0, 100) });\n\n try {\n const { stdout, stderr } = await execAsync(command, {\n timeout: effectiveTimeout,\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\n shell: '/bin/bash',\n });\n\n if (stderr && !stderr.includes('DeprecationWarning')) {\n logger.warn('CLI stderr output', { stderr: stderr.substring(0, 500) });\n }\n\n return stdout.trim();\n } catch (error) {\n const execError = error as ExecError;\n\n if (execError.code === 'ETIMEDOUT' || execError.killed) {\n throw new Error(`CLI command timed out after ${effectiveTimeout}ms`);\n }\n\n // Include any output in the error for debugging\n const message = execError.message || 'CLI execution failed';\n const details = execError.stderr || execError.stdout || '';\n throw new Error(`${message}${details ? `: ${details.substring(0, 200)}` : ''}`);\n }\n }\n\n private buildStoreCommand(\n key: string,\n value: string,\n namespace: string,\n ttl?: number\n ): string {\n const escapedValue = this.escapeShellArg(value);\n let command = `${this.config.cliCommand} memory store \"${key}\" ${escapedValue} --namespace \"${namespace}\"`;\n\n if (ttl !== undefined && ttl > 0) {\n command += ` --ttl ${ttl}`;\n }\n\n return command;\n }\n\n private buildQueryCommand(key: string, namespace: string): string {\n // Use query command to search for exact key\n return `${this.config.cliCommand} memory query \"${key}\" --namespace \"${namespace}\"`;\n }\n\n private buildSearchCommand(pattern: string, namespace: string, limit: number): string {\n return `${this.config.cliCommand} memory query \"${pattern}\" --namespace \"${namespace}\"`;\n }\n\n private buildDeleteCommand(key: string, namespace: string): string {\n // claude-flow uses 'clear' for deletion\n return `${this.config.cliCommand} memory clear --namespace \"${namespace}\"`;\n }\n\n private parseQueryOutput(output: string, key: string): string | null {\n if (!output || output.includes('not found') || output.includes('No results')) {\n return null;\n }\n\n // Try to parse as JSON first\n try {\n const parsed = JSON.parse(output);\n if (typeof parsed === 'object' && parsed !== null) {\n // Look for the key in the result\n if (key in parsed) {\n return typeof parsed[key] === 'string' ? parsed[key] : JSON.stringify(parsed[key]);\n }\n // Return the whole object as JSON string\n return JSON.stringify(parsed);\n }\n return String(parsed);\n } catch {\n // Return raw output\n return output;\n }\n }\n\n private parseSearchOutput(output: string): string[] {\n if (!output || output.includes('No results')) {\n return [];\n }\n\n // Try to parse as JSON array\n try {\n const parsed = JSON.parse(output);\n if (Array.isArray(parsed)) {\n return parsed.map((item) => (typeof item === 'string' ? item : JSON.stringify(item)));\n }\n if (typeof parsed === 'object' && parsed !== null) {\n return Object.keys(parsed);\n }\n } catch {\n // Parse line by line\n return output\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith('#'));\n }\n\n return [];\n }\n\n private parseListOutput(output: string): string[] {\n return this.parseSearchOutput(output);\n }\n\n private escapeShellArg(arg: string): string {\n // Escape for shell and wrap in quotes\n const escaped = arg\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/`/g, '\\\\`')\n .replace(/\\$/g, '\\\\$')\n .replace(/\\n/g, '\\\\n');\n return `\"${escaped}\"`;\n }\n\n // Fallback storage methods\n\n private getOrCreateNamespace(namespace: string): Map<string, FallbackEntry> {\n let ns = this.fallbackStore.get(namespace);\n if (!ns) {\n ns = new Map();\n this.fallbackStore.set(namespace, ns);\n }\n return ns;\n }\n\n private storeFallback(key: string, value: string, namespace: string, ttl?: number): void {\n const ns = this.getOrCreateNamespace(namespace);\n const now = Date.now();\n\n ns.set(key, {\n value,\n ttl,\n createdAt: now,\n expiresAt: ttl ? now + ttl * 1000 : undefined,\n });\n }\n\n private retrieveFallback(key: string, namespace: string): string | null {\n const ns = this.fallbackStore.get(namespace);\n if (!ns) return null;\n\n const entry = ns.get(key);\n if (!entry) return null;\n\n // Check expiration\n if (entry.expiresAt && Date.now() > entry.expiresAt) {\n ns.delete(key);\n return null;\n }\n\n return entry.value;\n }\n\n private searchFallback(pattern: string, namespace: string, limit: number): string[] {\n const ns = this.fallbackStore.get(namespace);\n if (!ns) return [];\n\n const now = Date.now();\n const results: string[] = [];\n\n // Convert glob pattern to regex\n const regexPattern = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*/g, '.*')\n .replace(/\\?/g, '.');\n const regex = new RegExp(`^${regexPattern}$`, 'i');\n\n for (const [key, entry] of ns) {\n if (results.length >= limit) break;\n\n // Skip expired entries\n if (entry.expiresAt && now > entry.expiresAt) {\n ns.delete(key);\n continue;\n }\n\n if (regex.test(key)) {\n results.push(key);\n }\n }\n\n return results;\n }\n\n private deleteFallback(key: string, namespace: string): boolean {\n const ns = this.fallbackStore.get(namespace);\n if (!ns) return false;\n return ns.delete(key);\n }\n\n private listFallback(namespace: string): string[] {\n const ns = this.fallbackStore.get(namespace);\n if (!ns) return [];\n\n const now = Date.now();\n const keys: string[] = [];\n\n for (const [key, entry] of ns) {\n // Skip expired entries\n if (entry.expiresAt && now > entry.expiresAt) {\n ns.delete(key);\n continue;\n }\n keys.push(key);\n }\n\n return keys;\n }\n}\n\n/**\n * Create a configured MCP client adapter\n */\nexport function createMcpClientAdapter(config?: Partial<McpClientConfig>): McpClientAdapter {\n return new McpClientAdapter(config);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mcp-client-adapter.js","sources":["../../../src/mcp/clients/mcp-client-adapter.ts"],"sourcesContent":["/**\n * MCP Client Adapter\n *\n * Provides real MCP tool execution via the claude-flow CLI with retry logic,\n * timeout handling, and graceful fallback to in-memory storage when CLI is unavailable.\n *\n * @module mcp/clients/mcp-client-adapter\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport {\n createLogger,\n withRetry,\n type RetryOptions,\n} from '../../utils/index.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Extended exec error type with additional properties\n */\ninterface ExecError extends Error {\n code?: string | number;\n killed?: boolean;\n stderr?: string;\n stdout?: string;\n}\nconst logger = createLogger('mcp-client-adapter');\n\n/**\n * MCP Client Configuration\n */\nexport interface McpClientConfig {\n /** Maximum number of retry attempts (default: 3) */\n maxRetries: number;\n\n /** Initial delay in milliseconds between retries (default: 1000) */\n retryDelayMs: number;\n\n /** Command execution timeout in milliseconds (default: 30000) */\n timeoutMs: number;\n\n /** Whether to fallback to in-memory storage when CLI unavailable (default: true) */\n fallbackEnabled: boolean;\n\n /** Claude-flow CLI command (default: 'claude-flow' or 'npx claude-flow') */\n cliCommand: string;\n\n /** Whether to use JSON output format from CLI when available */\n useJsonOutput: boolean;\n}\n\n/**\n * Result of a memory operation\n */\nexport interface MemoryOperationResult {\n /** Whether the operation succeeded */\n success: boolean;\n\n /** Result data (if successful) */\n data?: unknown;\n\n /** Error message (if failed) */\n error?: string;\n\n /** Whether the result came from fallback storage */\n fromFallback: boolean;\n\n /** Number of attempts made */\n attempts: number;\n}\n\n/**\n * Memory entry stored in fallback\n */\ninterface FallbackEntry {\n value: string;\n ttl?: number;\n createdAt: number;\n expiresAt?: number;\n}\n\n/**\n * MCP Client Adapter\n *\n * Executes real claude-flow CLI commands with robust retry logic and fallback.\n *\n * @example\n * ```typescript\n * const adapter = new McpClientAdapter({\n * maxRetries: 3,\n * timeoutMs: 30000,\n * });\n *\n * // Store value\n * await adapter.memoryStore('myKey', 'myValue', 'myNamespace');\n *\n * // Retrieve value\n * const value = await adapter.memoryRetrieve('myKey', 'myNamespace');\n * ```\n */\nexport class McpClientAdapter {\n private config: McpClientConfig;\n private fallbackStore: Map<string, Map<string, FallbackEntry>>;\n private cliAvailable: boolean | null = null;\n private lastCliCheck: number = 0;\n private readonly CLI_CHECK_INTERVAL = 60000; // Re-check CLI availability every 60s\n\n constructor(config: Partial<McpClientConfig> = {}) {\n this.config = {\n maxRetries: config.maxRetries ?? 3,\n retryDelayMs: config.retryDelayMs ?? 1000,\n timeoutMs: config.timeoutMs ?? 30000,\n fallbackEnabled: config.fallbackEnabled ?? true,\n cliCommand: config.cliCommand ?? 'claude-flow',\n useJsonOutput: config.useJsonOutput ?? true,\n };\n this.fallbackStore = new Map();\n }\n\n /**\n * Store a value in memory\n *\n * @param key - Memory key\n * @param value - Value to store (will be JSON stringified if object)\n * @param namespace - Memory namespace (default: 'default')\n * @param ttl - Time to live in seconds (optional)\n * @returns Whether the operation succeeded\n */\n async memoryStore(\n key: string,\n value: string | object,\n namespace: string = 'default',\n ttl?: number\n ): Promise<boolean> {\n const stringValue = typeof value === 'string' ? value : JSON.stringify(value);\n\n const result = await this.executeWithRetry(async () => {\n const command = this.buildStoreCommand(key, stringValue, namespace, ttl);\n await this.executeCli(command);\n return true;\n });\n\n if (result.success) {\n logger.debug('Memory store succeeded via CLI', { key, namespace });\n return true;\n }\n\n // Fallback to in-memory storage\n if (this.config.fallbackEnabled) {\n this.storeFallback(key, stringValue, namespace, ttl);\n logger.warn('Memory store fell back to in-memory', { key, namespace, error: result.error });\n return true;\n }\n\n logger.error('Memory store failed', undefined, { key, namespace, error: result.error });\n return false;\n }\n\n /**\n * Retrieve a value from memory\n *\n * @param key - Memory key\n * @param namespace - Memory namespace (default: 'default')\n * @returns The stored value or null if not found\n */\n async memoryRetrieve(key: string, namespace: string = 'default'): Promise<string | null> {\n const result = await this.executeWithRetry(async () => {\n const command = this.buildQueryCommand(key, namespace);\n const output = await this.executeCli(command);\n return this.parseQueryOutput(output, key);\n });\n\n if (result.success && result.value !== undefined) {\n logger.debug('Memory retrieve succeeded via CLI', { key, namespace });\n return result.value;\n }\n\n // Fallback to in-memory storage\n if (this.config.fallbackEnabled) {\n const fallbackValue = this.retrieveFallback(key, namespace);\n if (fallbackValue !== null) {\n logger.debug('Memory retrieve fell back to in-memory', { key, namespace });\n return fallbackValue;\n }\n }\n\n logger.debug('Memory retrieve returned null', { key, namespace });\n return null;\n }\n\n /**\n * Search memory by pattern\n *\n * @param pattern - Search pattern (supports glob-like matching)\n * @param namespace - Memory namespace (default: 'default')\n * @param limit - Maximum number of results (default: 10)\n * @returns Array of matching keys\n */\n async memorySearch(\n pattern: string,\n namespace: string = 'default',\n limit: number = 10\n ): Promise<string[]> {\n const result = await this.executeWithRetry(async () => {\n const command = this.buildSearchCommand(pattern, namespace, limit);\n const output = await this.executeCli(command);\n return this.parseSearchOutput(output);\n });\n\n if (result.success && result.value) {\n logger.debug('Memory search succeeded via CLI', { pattern, namespace, count: result.value.length });\n return result.value;\n }\n\n // Fallback to in-memory search\n if (this.config.fallbackEnabled) {\n const fallbackResults = this.searchFallback(pattern, namespace, limit);\n logger.debug('Memory search fell back to in-memory', { pattern, namespace, count: fallbackResults.length });\n return fallbackResults;\n }\n\n logger.debug('Memory search returned empty', { pattern, namespace });\n return [];\n }\n\n /**\n * Delete a value from memory\n *\n * @param key - Memory key\n * @param namespace - Memory namespace (default: 'default')\n * @returns Whether the operation succeeded\n */\n async memoryDelete(key: string, namespace: string = 'default'): Promise<boolean> {\n const result = await this.executeWithRetry(async () => {\n // Use clear command with specific key pattern\n const command = this.buildDeleteCommand(key, namespace);\n await this.executeCli(command);\n return true;\n });\n\n if (result.success) {\n logger.debug('Memory delete succeeded via CLI', { key, namespace });\n }\n\n // Also delete from fallback (regardless of CLI success)\n if (this.config.fallbackEnabled) {\n this.deleteFallback(key, namespace);\n }\n\n return result.success || this.config.fallbackEnabled;\n }\n\n /**\n * List all keys in a namespace\n *\n * @param namespace - Memory namespace (default: 'default')\n * @returns Array of keys\n */\n async memoryList(namespace: string = 'default'): Promise<string[]> {\n const result = await this.executeWithRetry(async () => {\n const command = `${this.config.cliCommand} memory list --namespace \"${namespace}\"`;\n const output = await this.executeCli(command);\n return this.parseListOutput(output);\n });\n\n if (result.success && result.value) {\n logger.debug('Memory list succeeded via CLI', { namespace, count: result.value.length });\n return result.value;\n }\n\n // Fallback\n if (this.config.fallbackEnabled) {\n const fallbackKeys = this.listFallback(namespace);\n logger.debug('Memory list fell back to in-memory', { namespace, count: fallbackKeys.length });\n return fallbackKeys;\n }\n\n return [];\n }\n\n /**\n * Check if CLI is available\n */\n async isCliAvailable(): Promise<boolean> {\n const now = Date.now();\n\n // Use cached result if recent\n if (this.cliAvailable !== null && now - this.lastCliCheck < this.CLI_CHECK_INTERVAL) {\n return this.cliAvailable;\n }\n\n try {\n await this.executeCli(`${this.config.cliCommand} --version`, 5000);\n this.cliAvailable = true;\n this.lastCliCheck = now;\n return true;\n } catch {\n this.cliAvailable = false;\n this.lastCliCheck = now;\n return false;\n }\n }\n\n /**\n * Get current configuration\n */\n getConfig(): Readonly<McpClientConfig> {\n return { ...this.config };\n }\n\n /**\n * Get fallback store size for a namespace\n */\n getFallbackSize(namespace: string = 'default'): number {\n return this.fallbackStore.get(namespace)?.size ?? 0;\n }\n\n /**\n * Clear fallback store\n */\n clearFallback(namespace?: string): void {\n if (namespace) {\n this.fallbackStore.delete(namespace);\n } else {\n this.fallbackStore.clear();\n }\n }\n\n // Private methods\n\n private async executeWithRetry<T>(\n operation: () => Promise<T>\n ): Promise<{ success: boolean; value?: T; error?: string; attempts: number }> {\n const retryOptions: RetryOptions = {\n maxRetries: this.config.maxRetries,\n initialDelay: this.config.retryDelayMs,\n backoffFactor: 2,\n jitter: true,\n onRetry: (error, attempt, delay) => {\n logger.debug('Retrying MCP operation', {\n attempt,\n delay,\n error: error.message,\n });\n },\n };\n\n const result = await withRetry(operation, retryOptions);\n\n return {\n success: result.success,\n value: result.value,\n error: result.error?.message,\n attempts: result.attempts,\n };\n }\n\n private async executeCli(command: string, timeout?: number): Promise<string> {\n const effectiveTimeout = timeout ?? this.config.timeoutMs;\n\n logger.debug('Executing CLI command', { command: command.substring(0, 100) });\n\n try {\n const { stdout, stderr } = await execAsync(command, {\n timeout: effectiveTimeout,\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\n shell: '/bin/bash',\n });\n\n if (stderr && !stderr.includes('DeprecationWarning')) {\n logger.warn('CLI stderr output', { stderr: stderr.substring(0, 500) });\n }\n\n return stdout.trim();\n } catch (error) {\n const execError = error as ExecError;\n\n if (execError.code === 'ETIMEDOUT' || execError.killed) {\n throw new Error(`CLI command timed out after ${effectiveTimeout}ms`);\n }\n\n // Include any output in the error for debugging\n const message = execError.message || 'CLI execution failed';\n const details = execError.stderr || execError.stdout || '';\n throw new Error(`${message}${details ? `: ${details.substring(0, 200)}` : ''}`);\n }\n }\n\n private buildStoreCommand(\n key: string,\n value: string,\n namespace: string,\n ttl?: number\n ): string {\n const escapedValue = this.escapeShellArg(value);\n let command = `${this.config.cliCommand} memory store \"${key}\" ${escapedValue} --namespace \"${namespace}\"`;\n\n if (ttl !== undefined && ttl > 0) {\n command += ` --ttl ${ttl}`;\n }\n\n return command;\n }\n\n private buildQueryCommand(key: string, namespace: string): string {\n // Use query command to search for exact key\n return `${this.config.cliCommand} memory query \"${key}\" --namespace \"${namespace}\"`;\n }\n\n private buildSearchCommand(pattern: string, namespace: string, limit: number): string {\n return `${this.config.cliCommand} memory query \"${pattern}\" --namespace \"${namespace}\"`;\n }\n\n private buildDeleteCommand(key: string, namespace: string): string {\n // claude-flow uses 'clear' for deletion\n return `${this.config.cliCommand} memory clear --namespace \"${namespace}\"`;\n }\n\n private parseQueryOutput(output: string, key: string): string | null {\n if (!output || output.includes('not found') || output.includes('No results')) {\n return null;\n }\n\n // Try to parse as JSON first\n try {\n const parsed = JSON.parse(output);\n if (typeof parsed === 'object' && parsed !== null) {\n // Look for the key in the result\n if (key in parsed) {\n return typeof parsed[key] === 'string' ? parsed[key] : JSON.stringify(parsed[key]);\n }\n // Return the whole object as JSON string\n return JSON.stringify(parsed);\n }\n return String(parsed);\n } catch {\n // Return raw output\n return output;\n }\n }\n\n private parseSearchOutput(output: string): string[] {\n if (!output || output.includes('No results')) {\n return [];\n }\n\n // Try to parse as JSON array\n try {\n const parsed = JSON.parse(output);\n if (Array.isArray(parsed)) {\n return parsed.map((item) => (typeof item === 'string' ? item : JSON.stringify(item)));\n }\n if (typeof parsed === 'object' && parsed !== null) {\n return Object.keys(parsed);\n }\n } catch {\n // Parse line by line\n return output\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith('#'));\n }\n\n return [];\n }\n\n private parseListOutput(output: string): string[] {\n return this.parseSearchOutput(output);\n }\n\n private escapeShellArg(arg: string): string {\n // Escape for shell and wrap in quotes\n const escaped = arg\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/`/g, '\\\\`')\n .replace(/\\$/g, '\\\\$')\n .replace(/\\n/g, '\\\\n');\n return `\"${escaped}\"`;\n }\n\n // Fallback storage methods\n\n private getOrCreateNamespace(namespace: string): Map<string, FallbackEntry> {\n let ns = this.fallbackStore.get(namespace);\n if (!ns) {\n ns = new Map();\n this.fallbackStore.set(namespace, ns);\n }\n return ns;\n }\n\n private storeFallback(key: string, value: string, namespace: string, ttl?: number): void {\n const ns = this.getOrCreateNamespace(namespace);\n const now = Date.now();\n\n ns.set(key, {\n value,\n ttl,\n createdAt: now,\n expiresAt: ttl ? now + ttl * 1000 : undefined,\n });\n }\n\n private retrieveFallback(key: string, namespace: string): string | null {\n const ns = this.fallbackStore.get(namespace);\n if (!ns) return null;\n\n const entry = ns.get(key);\n if (!entry) return null;\n\n // Check expiration\n if (entry.expiresAt && Date.now() > entry.expiresAt) {\n ns.delete(key);\n return null;\n }\n\n return entry.value;\n }\n\n private searchFallback(pattern: string, namespace: string, limit: number): string[] {\n const ns = this.fallbackStore.get(namespace);\n if (!ns) return [];\n\n const now = Date.now();\n const results: string[] = [];\n\n // Convert glob pattern to regex\n const regexPattern = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*/g, '.*')\n .replace(/\\?/g, '.');\n const regex = new RegExp(`^${regexPattern}$`, 'i');\n\n for (const [key, entry] of ns) {\n if (results.length >= limit) break;\n\n // Skip expired entries\n if (entry.expiresAt && now > entry.expiresAt) {\n ns.delete(key);\n continue;\n }\n\n if (regex.test(key)) {\n results.push(key);\n }\n }\n\n return results;\n }\n\n private deleteFallback(key: string, namespace: string): boolean {\n const ns = this.fallbackStore.get(namespace);\n if (!ns) return false;\n return ns.delete(key);\n }\n\n private listFallback(namespace: string): string[] {\n const ns = this.fallbackStore.get(namespace);\n if (!ns) return [];\n\n const now = Date.now();\n const keys: string[] = [];\n\n for (const [key, entry] of ns) {\n // Skip expired entries\n if (entry.expiresAt && now > entry.expiresAt) {\n ns.delete(key);\n continue;\n }\n keys.push(key);\n }\n\n return keys;\n }\n}\n\n/**\n * Create a configured MCP client adapter\n */\nexport function createMcpClientAdapter(config?: Partial<McpClientConfig>): McpClientAdapter {\n return new McpClientAdapter(config);\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weavelogic/knowledge-graph-agent",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"description": "Knowledge graph agent for Claude Code - generates knowledge graphs, initializes docs, and integrates with claude-flow",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|