claude-flow 2.7.31 ā 2.7.32
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/CHANGELOG.md +19 -0
- package/bin/claude-flow +1 -1
- package/dist/src/cli/help-formatter.js +3 -0
- package/dist/src/cli/help-formatter.js.map +1 -1
- package/dist/src/cli/simple-commands/memory.js +67 -17
- package/dist/src/cli/simple-commands/memory.js.map +1 -1
- package/dist/src/cli/validation-helper.js.map +1 -1
- package/dist/src/core/version.js.map +1 -1
- package/dist/src/memory/swarm-memory.js +421 -340
- package/dist/src/memory/swarm-memory.js.map +1 -1
- package/dist/src/utils/key-redactor.js.map +1 -1
- package/docs/BUG_REPORT_MEMORY_STATS.md +355 -0
- package/docs/FIX_VERIFICATION_MEMORY_STATS.md +235 -0
- package/docs/RECENT_RELEASES_SUMMARY.md +375 -0
- package/docs/V2.7.31_RELEASE_NOTES.md +375 -0
- package/package.json +1 -1
- package/src/cli/simple-commands/memory.js +93 -19
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/memory/swarm-memory.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport { Logger } from '../core/logger.js';\nimport { MemoryManager } from './manager.js';\nimport { EventBus } from '../core/event-bus.js';\nimport { generateId } from '../utils/helpers.js';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport interface SwarmMemoryEntry {\n id: string;\n agentId: string;\n type: 'knowledge' | 'result' | 'state' | 'communication' | 'error';\n content: any;\n timestamp: Date;\n metadata: {\n taskId?: string;\n objectiveId?: string;\n tags?: string[];\n priority?: number;\n shareLevel?: 'private' | 'team' | 'public';\n };\n}\n\nexport interface SwarmMemoryQuery {\n agentId?: string;\n type?: SwarmMemoryEntry['type'];\n taskId?: string;\n objectiveId?: string;\n tags?: string[];\n since?: Date;\n before?: Date;\n limit?: number;\n shareLevel?: SwarmMemoryEntry['metadata']['shareLevel'];\n}\n\nexport interface SwarmKnowledgeBase {\n id: string;\n name: string;\n description: string;\n entries: SwarmMemoryEntry[];\n metadata: {\n domain: string;\n expertise: string[];\n contributors: string[];\n lastUpdated: Date;\n };\n}\n\nexport interface SwarmMemoryConfig {\n namespace: string;\n enableDistribution: boolean;\n enableReplication: boolean;\n syncInterval: number;\n maxEntries: number;\n compressionThreshold: number;\n enableKnowledgeBase: boolean;\n enableCrossAgentSharing: boolean;\n persistencePath: string;\n}\n\nexport class SwarmMemoryManager extends EventEmitter {\n private logger: Logger;\n private config: SwarmMemoryConfig;\n private baseMemory: MemoryManager;\n private entries: Map<string, SwarmMemoryEntry>;\n private knowledgeBases: Map<string, SwarmKnowledgeBase>;\n private agentMemories: Map<string, Set<string>>; // agentId -> set of entry IDs\n private syncTimer?: NodeJS.Timeout;\n private isInitialized: boolean = false;\n\n constructor(config: Partial<SwarmMemoryConfig> = {}) {\n super();\n this.logger = new Logger('SwarmMemoryManager');\n this.config = {\n namespace: 'swarm',\n enableDistribution: true,\n enableReplication: true,\n syncInterval: 10000, // 10 seconds\n maxEntries: 10000,\n compressionThreshold: 1000,\n enableKnowledgeBase: true,\n enableCrossAgentSharing: true,\n persistencePath: './swarm-memory',\n ...config,\n };\n\n this.entries = new Map();\n this.knowledgeBases = new Map();\n this.agentMemories = new Map();\n\n const eventBus = EventBus.getInstance();\n this.baseMemory = new MemoryManager(\n {\n backend: 'sqlite',\n namespace: this.config.namespace,\n cacheSizeMB: 50,\n syncOnExit: true,\n maxEntries: this.config.maxEntries,\n ttlMinutes: 60,\n },\n eventBus,\n this.logger,\n );\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) return;\n\n this.logger.info('Initializing swarm memory manager...');\n\n // Initialize base memory\n await this.baseMemory.initialize();\n\n // Create persistence directory\n await fs.mkdir(this.config.persistencePath, { recursive: true });\n\n // Load existing memory\n await this.loadMemoryState();\n\n // Start sync timer\n if (this.config.syncInterval > 0) {\n this.syncTimer = setInterval(() => {\n this.syncMemoryState();\n }, this.config.syncInterval);\n }\n\n this.isInitialized = true;\n this.emit('memory:initialized');\n }\n\n async shutdown(): Promise<void> {\n if (!this.isInitialized) return;\n\n this.logger.info('Shutting down swarm memory manager...');\n\n // Stop sync timer\n if (this.syncTimer) {\n clearInterval(this.syncTimer);\n this.syncTimer = undefined;\n }\n\n // Save final state\n await this.saveMemoryState();\n\n this.isInitialized = false;\n this.emit('memory:shutdown');\n }\n\n async remember(\n agentId: string,\n type: SwarmMemoryEntry['type'],\n content: any,\n metadata: Partial<SwarmMemoryEntry['metadata']> = {},\n ): Promise<string> {\n const entryId = generateId('mem');\n const entry: SwarmMemoryEntry = {\n id: entryId,\n agentId,\n type,\n content,\n timestamp: new Date(),\n metadata: {\n shareLevel: 'team',\n priority: 1,\n ...metadata,\n },\n };\n\n this.entries.set(entryId, entry);\n\n // Associate with agent\n if (!this.agentMemories.has(agentId)) {\n this.agentMemories.set(agentId, new Set());\n }\n this.agentMemories.get(agentId)!.add(entryId);\n\n // Store in base memory for persistence\n await this.baseMemory.remember({\n namespace: this.config.namespace,\n key: `entry:${entryId}`,\n content: JSON.stringify(entry),\n metadata: {\n type: 'swarm-memory',\n agentId,\n entryType: type,\n shareLevel: entry.metadata.shareLevel,\n },\n });\n\n this.logger.debug(`Agent ${agentId} remembered: ${type} - ${entryId}`);\n this.emit('memory:added', entry);\n\n // Update knowledge base if applicable\n if (type === 'knowledge' && this.config.enableKnowledgeBase) {\n await this.updateKnowledgeBase(entry);\n }\n\n // Check for memory limits\n await this.enforceMemoryLimits();\n\n return entryId;\n }\n\n async recall(query: SwarmMemoryQuery): Promise<SwarmMemoryEntry[]> {\n let results = Array.from(this.entries.values());\n\n // Apply filters\n if (query.agentId) {\n results = results.filter((e) => e.agentId === query.agentId);\n }\n\n if (query.type) {\n results = results.filter((e) => e.type === query.type);\n }\n\n if (query.taskId) {\n results = results.filter((e) => e.metadata.taskId === query.taskId);\n }\n\n if (query.objectiveId) {\n results = results.filter((e) => e.metadata.objectiveId === query.objectiveId);\n }\n\n if (query.tags && query.tags.length > 0) {\n results = results.filter(\n (e) => e.metadata.tags && query.tags!.some((tag) => e.metadata.tags!.includes(tag)),\n );\n }\n\n if (query.since) {\n results = results.filter((e) => e.timestamp >= query.since!);\n }\n\n if (query.before) {\n results = results.filter((e) => e.timestamp <= query.before!);\n }\n\n if (query.shareLevel) {\n results = results.filter((e) => e.metadata.shareLevel === query.shareLevel);\n }\n\n // Sort by timestamp (newest first)\n results.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n\n // Apply limit\n if (query.limit) {\n results = results.slice(0, query.limit);\n }\n\n this.logger.debug(`Recalled ${results.length} memories for query`);\n return results;\n }\n\n async shareMemory(entryId: string, targetAgentId: string): Promise<void> {\n const entry = this.entries.get(entryId);\n if (!entry) {\n throw new Error('Memory entry not found');\n }\n\n if (!this.config.enableCrossAgentSharing) {\n throw new Error('Cross-agent sharing is disabled');\n }\n\n // Check share level permissions\n if (entry.metadata.shareLevel === 'private') {\n throw new Error('Memory entry is private and cannot be shared');\n }\n\n // Create a shared copy for the target agent\n const sharedEntry: SwarmMemoryEntry = {\n ...entry,\n id: generateId('mem'),\n metadata: {\n ...entry.metadata,\n originalId: entryId,\n sharedFrom: entry.agentId,\n sharedTo: targetAgentId,\n sharedAt: new Date(),\n },\n };\n\n this.entries.set(sharedEntry.id, sharedEntry);\n\n // Associate with target agent\n if (!this.agentMemories.has(targetAgentId)) {\n this.agentMemories.set(targetAgentId, new Set());\n }\n this.agentMemories.get(targetAgentId)!.add(sharedEntry.id);\n\n this.logger.info(`Shared memory ${entryId} from ${entry.agentId} to ${targetAgentId}`);\n this.emit('memory:shared', { original: entry, shared: sharedEntry });\n }\n\n async broadcastMemory(entryId: string, agentIds?: string[]): Promise<void> {\n const entry = this.entries.get(entryId);\n if (!entry) {\n throw new Error('Memory entry not found');\n }\n\n if (entry.metadata.shareLevel === 'private') {\n throw new Error('Cannot broadcast private memory');\n }\n\n const targets =\n agentIds || Array.from(this.agentMemories.keys()).filter((id) => id !== entry.agentId);\n\n for (const targetId of targets) {\n try {\n await this.shareMemory(entryId, targetId);\n } catch (error) {\n this.logger.warn(`Failed to share memory to ${targetId}:`, error);\n }\n }\n\n this.logger.info(`Broadcasted memory ${entryId} to ${targets.length} agents`);\n }\n\n async createKnowledgeBase(\n name: string,\n description: string,\n domain: string,\n expertise: string[],\n ): Promise<string> {\n const kbId = generateId('kb');\n const knowledgeBase: SwarmKnowledgeBase = {\n id: kbId,\n name,\n description,\n entries: [],\n metadata: {\n domain,\n expertise,\n contributors: [],\n lastUpdated: new Date(),\n },\n };\n\n this.knowledgeBases.set(kbId, knowledgeBase);\n\n this.logger.info(`Created knowledge base: ${name} (${kbId})`);\n this.emit('knowledgebase:created', knowledgeBase);\n\n return kbId;\n }\n\n async updateKnowledgeBase(entry: SwarmMemoryEntry): Promise<void> {\n if (!this.config.enableKnowledgeBase) return;\n\n // Find relevant knowledge bases\n const relevantKBs = Array.from(this.knowledgeBases.values()).filter((kb) => {\n // Simple matching based on tags and content\n const tags = entry.metadata.tags || [];\n return tags.some((tag) =>\n kb.metadata.expertise.some(\n (exp) =>\n exp.toLowerCase().includes(tag.toLowerCase()) ||\n tag.toLowerCase().includes(exp.toLowerCase()),\n ),\n );\n });\n\n for (const kb of relevantKBs) {\n // Add entry to knowledge base\n kb.entries.push(entry);\n kb.metadata.lastUpdated = new Date();\n\n // Add contributor\n if (!kb.metadata.contributors.includes(entry.agentId)) {\n kb.metadata.contributors.push(entry.agentId);\n }\n\n this.logger.debug(`Updated knowledge base ${kb.id} with entry ${entry.id}`);\n }\n }\n\n async searchKnowledge(\n query: string,\n domain?: string,\n expertise?: string[],\n ): Promise<SwarmMemoryEntry[]> {\n const allEntries: SwarmMemoryEntry[] = [];\n\n // Search in knowledge bases\n for (const kb of this.knowledgeBases.values()) {\n if (domain && kb.metadata.domain !== domain) continue;\n\n if (expertise && !expertise.some((exp) => kb.metadata.expertise.includes(exp))) {\n continue;\n }\n\n allEntries.push(...kb.entries);\n }\n\n // Simple text search (in real implementation, use better search)\n const queryLower = query.toLowerCase();\n const results = allEntries.filter((entry) => {\n const contentStr = JSON.stringify(entry.content).toLowerCase();\n return contentStr.includes(queryLower);\n });\n\n return results.slice(0, 50); // Limit results\n }\n\n async getAgentMemorySnapshot(agentId: string): Promise<{\n totalEntries: number;\n recentEntries: SwarmMemoryEntry[];\n knowledgeContributions: number;\n sharedEntries: number;\n }> {\n const agentEntryIds = this.agentMemories.get(agentId) || new Set();\n const agentEntries = Array.from(agentEntryIds)\n .map((id) => this.entries.get(id))\n .filter(Boolean) as SwarmMemoryEntry[];\n\n const recentEntries = agentEntries\n .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())\n .slice(0, 10);\n\n const knowledgeContributions = agentEntries.filter((e) => e.type === 'knowledge').length;\n\n const sharedEntries = agentEntries.filter(\n (e) => e.metadata.shareLevel === 'public' || e.metadata.shareLevel === 'team',\n ).length;\n\n return {\n totalEntries: agentEntries.length,\n recentEntries,\n knowledgeContributions,\n sharedEntries,\n };\n }\n\n private async loadMemoryState(): Promise<void> {\n try {\n // Load entries\n const entriesFile = path.join(this.config.persistencePath, 'entries.json');\n try {\n const entriesData = await fs.readFile(entriesFile, 'utf-8');\n const entriesArray = JSON.parse(entriesData);\n\n for (const entry of entriesArray) {\n this.entries.set(entry.id, {\n ...entry,\n timestamp: new Date(entry.timestamp),\n });\n\n // Rebuild agent memory associations\n if (!this.agentMemories.has(entry.agentId)) {\n this.agentMemories.set(entry.agentId, new Set());\n }\n this.agentMemories.get(entry.agentId)!.add(entry.id);\n }\n\n this.logger.info(`Loaded ${entriesArray.length} memory entries`);\n } catch (error) {\n this.logger.warn('No existing memory entries found');\n }\n\n // Load knowledge bases\n const kbFile = path.join(this.config.persistencePath, 'knowledge-bases.json');\n try {\n const kbData = await fs.readFile(kbFile, 'utf-8');\n const kbArray = JSON.parse(kbData);\n\n for (const kb of kbArray) {\n this.knowledgeBases.set(kb.id, {\n ...kb,\n metadata: {\n ...kb.metadata,\n lastUpdated: new Date(kb.metadata.lastUpdated),\n },\n entries: kb.entries.map((e: any) => ({\n ...e,\n timestamp: new Date(e.timestamp),\n })),\n });\n }\n\n this.logger.info(`Loaded ${kbArray.length} knowledge bases`);\n } catch (error) {\n this.logger.warn('No existing knowledge bases found');\n }\n } catch (error) {\n this.logger.error('Error loading memory state:', error);\n }\n }\n\n private async saveMemoryState(): Promise<void> {\n try {\n // Save entries\n const entriesArray = Array.from(this.entries.values());\n const entriesFile = path.join(this.config.persistencePath, 'entries.json');\n await fs.writeFile(entriesFile, JSON.stringify(entriesArray, null, 2));\n\n // Save knowledge bases\n const kbArray = Array.from(this.knowledgeBases.values());\n const kbFile = path.join(this.config.persistencePath, 'knowledge-bases.json');\n await fs.writeFile(kbFile, JSON.stringify(kbArray, null, 2));\n\n this.logger.debug('Saved memory state to disk');\n } catch (error) {\n this.logger.error('Error saving memory state:', error);\n }\n }\n\n private async syncMemoryState(): Promise<void> {\n try {\n await this.saveMemoryState();\n this.emit('memory:synced');\n } catch (error) {\n this.logger.error('Error syncing memory state:', error);\n }\n }\n\n private async enforceMemoryLimits(): Promise<void> {\n if (this.entries.size <= this.config.maxEntries) return;\n\n this.logger.info('Enforcing memory limits...');\n\n // Remove oldest entries that are not marked as important\n const entries = Array.from(this.entries.values())\n .filter((e) => (e.metadata.priority || 1) <= 1) // Only remove low priority\n .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());\n\n const toRemove = entries.slice(0, this.entries.size - this.config.maxEntries);\n\n for (const entry of toRemove) {\n this.entries.delete(entry.id);\n\n // Remove from agent memory\n const agentEntries = this.agentMemories.get(entry.agentId);\n if (agentEntries) {\n agentEntries.delete(entry.id);\n }\n\n this.logger.debug(`Removed old memory entry: ${entry.id}`);\n }\n\n this.emit('memory:cleaned', toRemove.length);\n }\n\n // Public API methods\n getMemoryStats(): {\n totalEntries: number;\n entriesByType: Record<string, number>;\n entriesByAgent: Record<string, number>;\n knowledgeBases: number;\n memoryUsage: number;\n } {\n const entries = Array.from(this.entries.values());\n const entriesByType: Record<string, number> = {};\n const entriesByAgent: Record<string, number> = {};\n\n for (const entry of entries) {\n entriesByType[entry.type] = (entriesByType[entry.type] || 0) + 1;\n entriesByAgent[entry.agentId] = (entriesByAgent[entry.agentId] || 0) + 1;\n }\n\n // Rough memory usage calculation\n const memoryUsage = JSON.stringify(entries).length;\n\n return {\n totalEntries: entries.length,\n entriesByType,\n entriesByAgent,\n knowledgeBases: this.knowledgeBases.size,\n memoryUsage,\n };\n }\n\n async exportMemory(agentId?: string): Promise<any> {\n const entries = agentId ? await this.recall({ agentId }) : Array.from(this.entries.values());\n\n return {\n entries,\n knowledgeBases: agentId\n ? Array.from(this.knowledgeBases.values()).filter((kb) =>\n kb.metadata.contributors.includes(agentId),\n )\n : Array.from(this.knowledgeBases.values()),\n exportedAt: new Date(),\n stats: this.getMemoryStats(),\n };\n }\n\n async clearMemory(agentId?: string): Promise<void> {\n if (agentId) {\n // Clear specific agent's memory\n const entryIds = this.agentMemories.get(agentId) || new Set();\n for (const entryId of entryIds) {\n this.entries.delete(entryId);\n }\n this.agentMemories.delete(agentId);\n this.logger.info(`Cleared memory for agent ${agentId}`);\n } else {\n // Clear all memory\n this.entries.clear();\n this.agentMemories.clear();\n this.knowledgeBases.clear();\n this.logger.info('Cleared all swarm memory');\n }\n\n this.emit('memory:cleared', { agentId });\n }\n\n // Compatibility methods for hive.ts\n async store(key: string, value: any): Promise<void> {\n // Extract namespace and actual key from the path\n const parts = key.split('/');\n const type = (parts[0] as SwarmMemoryEntry['type']) || 'state';\n const agentId = parts[1] || 'system';\n\n await this.remember(agentId, type, value, {\n tags: [parts[0], parts[1]].filter(Boolean),\n shareLevel: 'team',\n });\n }\n\n async search(pattern: string, limit: number = 10): Promise<any[]> {\n // Simple pattern matching on stored keys/content\n const results: any[] = [];\n\n for (const entry of this.entries.values()) {\n const entryString = JSON.stringify(entry);\n if (entryString.includes(pattern.replace('*', ''))) {\n results.push(entry.content);\n if (results.length >= limit) break;\n }\n }\n\n return results;\n }\n}\n"],"names":["EventEmitter","Logger","MemoryManager","EventBus","generateId","fs","path","SwarmMemoryManager","logger","config","baseMemory","entries","knowledgeBases","agentMemories","syncTimer","isInitialized","namespace","enableDistribution","enableReplication","syncInterval","maxEntries","compressionThreshold","enableKnowledgeBase","enableCrossAgentSharing","persistencePath","Map","eventBus","getInstance","backend","cacheSizeMB","syncOnExit","ttlMinutes","initialize","info","mkdir","recursive","loadMemoryState","setInterval","syncMemoryState","emit","shutdown","clearInterval","undefined","saveMemoryState","remember","agentId","type","content","metadata","entryId","entry","id","timestamp","Date","shareLevel","priority","set","has","Set","get","add","key","JSON","stringify","entryType","debug","updateKnowledgeBase","enforceMemoryLimits","recall","query","results","Array","from","values","filter","e","taskId","objectiveId","tags","length","some","tag","includes","since","before","sort","a","b","getTime","limit","slice","shareMemory","targetAgentId","Error","sharedEntry","originalId","sharedFrom","sharedTo","sharedAt","original","shared","broadcastMemory","agentIds","targets","keys","targetId","error","warn","createKnowledgeBase","name","description","domain","expertise","kbId","knowledgeBase","contributors","lastUpdated","relevantKBs","kb","exp","toLowerCase","push","searchKnowledge","allEntries","queryLower","contentStr","getAgentMemorySnapshot","agentEntryIds","agentEntries","map","Boolean","recentEntries","knowledgeContributions","sharedEntries","totalEntries","entriesFile","join","entriesData","readFile","entriesArray","parse","kbFile","kbData","kbArray","writeFile","size","toRemove","delete","getMemoryStats","entriesByType","entriesByAgent","memoryUsage","exportMemory","exportedAt","stats","clearMemory","entryIds","clear","store","value","parts","split","search","pattern","entryString","replace"],"mappings":"AAAA,SAASA,YAAY,QAAQ,cAAc;AAC3C,SAASC,MAAM,QAAQ,oBAAoB;AAC3C,SAASC,aAAa,QAAQ,eAAe;AAC7C,SAASC,QAAQ,QAAQ,uBAAuB;AAChD,SAASC,UAAU,QAAQ,sBAAsB;AACjD,YAAYC,QAAQ,mBAAmB;AACvC,YAAYC,UAAU,YAAY;AAsDlC,OAAO,MAAMC,2BAA2BP;IAC9BQ,OAAe;IACfC,OAA0B;IAC1BC,WAA0B;IAC1BC,QAAuC;IACvCC,eAAgD;IAChDC,cAAwC;IACxCC,UAA2B;IAC3BC,gBAAyB,MAAM;IAEvC,YAAYN,SAAqC,CAAC,CAAC,CAAE;QACnD,KAAK;QACL,IAAI,CAACD,MAAM,GAAG,IAAIP,OAAO;QACzB,IAAI,CAACQ,MAAM,GAAG;YACZO,WAAW;YACXC,oBAAoB;YACpBC,mBAAmB;YACnBC,cAAc;YACdC,YAAY;YACZC,sBAAsB;YACtBC,qBAAqB;YACrBC,yBAAyB;YACzBC,iBAAiB;YACjB,GAAGf,MAAM;QACX;QAEA,IAAI,CAACE,OAAO,GAAG,IAAIc;QACnB,IAAI,CAACb,cAAc,GAAG,IAAIa;QAC1B,IAAI,CAACZ,aAAa,GAAG,IAAIY;QAEzB,MAAMC,WAAWvB,SAASwB,WAAW;QACrC,IAAI,CAACjB,UAAU,GAAG,IAAIR,cACpB;YACE0B,SAAS;YACTZ,WAAW,IAAI,CAACP,MAAM,CAACO,SAAS;YAChCa,aAAa;YACbC,YAAY;YACZV,YAAY,IAAI,CAACX,MAAM,CAACW,UAAU;YAClCW,YAAY;QACd,GACAL,UACA,IAAI,CAAClB,MAAM;IAEf;IAEA,MAAMwB,aAA4B;QAChC,IAAI,IAAI,CAACjB,aAAa,EAAE;QAExB,IAAI,CAACP,MAAM,CAACyB,IAAI,CAAC;QAGjB,MAAM,IAAI,CAACvB,UAAU,CAACsB,UAAU;QAGhC,MAAM3B,GAAG6B,KAAK,CAAC,IAAI,CAACzB,MAAM,CAACe,eAAe,EAAE;YAAEW,WAAW;QAAK;QAG9D,MAAM,IAAI,CAACC,eAAe;QAG1B,IAAI,IAAI,CAAC3B,MAAM,CAACU,YAAY,GAAG,GAAG;YAChC,IAAI,CAACL,SAAS,GAAGuB,YAAY;gBAC3B,IAAI,CAACC,eAAe;YACtB,GAAG,IAAI,CAAC7B,MAAM,CAACU,YAAY;QAC7B;QAEA,IAAI,CAACJ,aAAa,GAAG;QACrB,IAAI,CAACwB,IAAI,CAAC;IACZ;IAEA,MAAMC,WAA0B;QAC9B,IAAI,CAAC,IAAI,CAACzB,aAAa,EAAE;QAEzB,IAAI,CAACP,MAAM,CAACyB,IAAI,CAAC;QAGjB,IAAI,IAAI,CAACnB,SAAS,EAAE;YAClB2B,cAAc,IAAI,CAAC3B,SAAS;YAC5B,IAAI,CAACA,SAAS,GAAG4B;QACnB;QAGA,MAAM,IAAI,CAACC,eAAe;QAE1B,IAAI,CAAC5B,aAAa,GAAG;QACrB,IAAI,CAACwB,IAAI,CAAC;IACZ;IAEA,MAAMK,SACJC,OAAe,EACfC,IAA8B,EAC9BC,OAAY,EACZC,WAAkD,CAAC,CAAC,EACnC;QACjB,MAAMC,UAAU7C,WAAW;QAC3B,MAAM8C,QAA0B;YAC9BC,IAAIF;YACJJ;YACAC;YACAC;YACAK,WAAW,IAAIC;YACfL,UAAU;gBACRM,YAAY;gBACZC,UAAU;gBACV,GAAGP,QAAQ;YACb;QACF;QAEA,IAAI,CAACrC,OAAO,CAAC6C,GAAG,CAACP,SAASC;QAG1B,IAAI,CAAC,IAAI,CAACrC,aAAa,CAAC4C,GAAG,CAACZ,UAAU;YACpC,IAAI,CAAChC,aAAa,CAAC2C,GAAG,CAACX,SAAS,IAAIa;QACtC;QACA,IAAI,CAAC7C,aAAa,CAAC8C,GAAG,CAACd,SAAUe,GAAG,CAACX;QAGrC,MAAM,IAAI,CAACvC,UAAU,CAACkC,QAAQ,CAAC;YAC7B5B,WAAW,IAAI,CAACP,MAAM,CAACO,SAAS;YAChC6C,KAAK,CAAC,MAAM,EAAEZ,SAAS;YACvBF,SAASe,KAAKC,SAAS,CAACb;YACxBF,UAAU;gBACRF,MAAM;gBACND;gBACAmB,WAAWlB;gBACXQ,YAAYJ,MAAMF,QAAQ,CAACM,UAAU;YACvC;QACF;QAEA,IAAI,CAAC9C,MAAM,CAACyD,KAAK,CAAC,CAAC,MAAM,EAAEpB,QAAQ,aAAa,EAAEC,KAAK,GAAG,EAAEG,SAAS;QACrE,IAAI,CAACV,IAAI,CAAC,gBAAgBW;QAG1B,IAAIJ,SAAS,eAAe,IAAI,CAACrC,MAAM,CAACa,mBAAmB,EAAE;YAC3D,MAAM,IAAI,CAAC4C,mBAAmB,CAAChB;QACjC;QAGA,MAAM,IAAI,CAACiB,mBAAmB;QAE9B,OAAOlB;IACT;IAEA,MAAMmB,OAAOC,KAAuB,EAA+B;QACjE,IAAIC,UAAUC,MAAMC,IAAI,CAAC,IAAI,CAAC7D,OAAO,CAAC8D,MAAM;QAG5C,IAAIJ,MAAMxB,OAAO,EAAE;YACjByB,UAAUA,QAAQI,MAAM,CAAC,CAACC,IAAMA,EAAE9B,OAAO,KAAKwB,MAAMxB,OAAO;QAC7D;QAEA,IAAIwB,MAAMvB,IAAI,EAAE;YACdwB,UAAUA,QAAQI,MAAM,CAAC,CAACC,IAAMA,EAAE7B,IAAI,KAAKuB,MAAMvB,IAAI;QACvD;QAEA,IAAIuB,MAAMO,MAAM,EAAE;YAChBN,UAAUA,QAAQI,MAAM,CAAC,CAACC,IAAMA,EAAE3B,QAAQ,CAAC4B,MAAM,KAAKP,MAAMO,MAAM;QACpE;QAEA,IAAIP,MAAMQ,WAAW,EAAE;YACrBP,UAAUA,QAAQI,MAAM,CAAC,CAACC,IAAMA,EAAE3B,QAAQ,CAAC6B,WAAW,KAAKR,MAAMQ,WAAW;QAC9E;QAEA,IAAIR,MAAMS,IAAI,IAAIT,MAAMS,IAAI,CAACC,MAAM,GAAG,GAAG;YACvCT,UAAUA,QAAQI,MAAM,CACtB,CAACC,IAAMA,EAAE3B,QAAQ,CAAC8B,IAAI,IAAIT,MAAMS,IAAI,CAAEE,IAAI,CAAC,CAACC,MAAQN,EAAE3B,QAAQ,CAAC8B,IAAI,CAAEI,QAAQ,CAACD;QAElF;QAEA,IAAIZ,MAAMc,KAAK,EAAE;YACfb,UAAUA,QAAQI,MAAM,CAAC,CAACC,IAAMA,EAAEvB,SAAS,IAAIiB,MAAMc,KAAK;QAC5D;QAEA,IAAId,MAAMe,MAAM,EAAE;YAChBd,UAAUA,QAAQI,MAAM,CAAC,CAACC,IAAMA,EAAEvB,SAAS,IAAIiB,MAAMe,MAAM;QAC7D;QAEA,IAAIf,MAAMf,UAAU,EAAE;YACpBgB,UAAUA,QAAQI,MAAM,CAAC,CAACC,IAAMA,EAAE3B,QAAQ,CAACM,UAAU,KAAKe,MAAMf,UAAU;QAC5E;QAGAgB,QAAQe,IAAI,CAAC,CAACC,GAAGC,IAAMA,EAAEnC,SAAS,CAACoC,OAAO,KAAKF,EAAElC,SAAS,CAACoC,OAAO;QAGlE,IAAInB,MAAMoB,KAAK,EAAE;YACfnB,UAAUA,QAAQoB,KAAK,CAAC,GAAGrB,MAAMoB,KAAK;QACxC;QAEA,IAAI,CAACjF,MAAM,CAACyD,KAAK,CAAC,CAAC,SAAS,EAAEK,QAAQS,MAAM,CAAC,mBAAmB,CAAC;QACjE,OAAOT;IACT;IAEA,MAAMqB,YAAY1C,OAAe,EAAE2C,aAAqB,EAAiB;QACvE,MAAM1C,QAAQ,IAAI,CAACvC,OAAO,CAACgD,GAAG,CAACV;QAC/B,IAAI,CAACC,OAAO;YACV,MAAM,IAAI2C,MAAM;QAClB;QAEA,IAAI,CAAC,IAAI,CAACpF,MAAM,CAACc,uBAAuB,EAAE;YACxC,MAAM,IAAIsE,MAAM;QAClB;QAGA,IAAI3C,MAAMF,QAAQ,CAACM,UAAU,KAAK,WAAW;YAC3C,MAAM,IAAIuC,MAAM;QAClB;QAGA,MAAMC,cAAgC;YACpC,GAAG5C,KAAK;YACRC,IAAI/C,WAAW;YACf4C,UAAU;gBACR,GAAGE,MAAMF,QAAQ;gBACjB+C,YAAY9C;gBACZ+C,YAAY9C,MAAML,OAAO;gBACzBoD,UAAUL;gBACVM,UAAU,IAAI7C;YAChB;QACF;QAEA,IAAI,CAAC1C,OAAO,CAAC6C,GAAG,CAACsC,YAAY3C,EAAE,EAAE2C;QAGjC,IAAI,CAAC,IAAI,CAACjF,aAAa,CAAC4C,GAAG,CAACmC,gBAAgB;YAC1C,IAAI,CAAC/E,aAAa,CAAC2C,GAAG,CAACoC,eAAe,IAAIlC;QAC5C;QACA,IAAI,CAAC7C,aAAa,CAAC8C,GAAG,CAACiC,eAAgBhC,GAAG,CAACkC,YAAY3C,EAAE;QAEzD,IAAI,CAAC3C,MAAM,CAACyB,IAAI,CAAC,CAAC,cAAc,EAAEgB,QAAQ,MAAM,EAAEC,MAAML,OAAO,CAAC,IAAI,EAAE+C,eAAe;QACrF,IAAI,CAACrD,IAAI,CAAC,iBAAiB;YAAE4D,UAAUjD;YAAOkD,QAAQN;QAAY;IACpE;IAEA,MAAMO,gBAAgBpD,OAAe,EAAEqD,QAAmB,EAAiB;QACzE,MAAMpD,QAAQ,IAAI,CAACvC,OAAO,CAACgD,GAAG,CAACV;QAC/B,IAAI,CAACC,OAAO;YACV,MAAM,IAAI2C,MAAM;QAClB;QAEA,IAAI3C,MAAMF,QAAQ,CAACM,UAAU,KAAK,WAAW;YAC3C,MAAM,IAAIuC,MAAM;QAClB;QAEA,MAAMU,UACJD,YAAY/B,MAAMC,IAAI,CAAC,IAAI,CAAC3D,aAAa,CAAC2F,IAAI,IAAI9B,MAAM,CAAC,CAACvB,KAAOA,OAAOD,MAAML,OAAO;QAEvF,KAAK,MAAM4D,YAAYF,QAAS;YAC9B,IAAI;gBACF,MAAM,IAAI,CAACZ,WAAW,CAAC1C,SAASwD;YAClC,EAAE,OAAOC,OAAO;gBACd,IAAI,CAAClG,MAAM,CAACmG,IAAI,CAAC,CAAC,0BAA0B,EAAEF,SAAS,CAAC,CAAC,EAAEC;YAC7D;QACF;QAEA,IAAI,CAAClG,MAAM,CAACyB,IAAI,CAAC,CAAC,mBAAmB,EAAEgB,QAAQ,IAAI,EAAEsD,QAAQxB,MAAM,CAAC,OAAO,CAAC;IAC9E;IAEA,MAAM6B,oBACJC,IAAY,EACZC,WAAmB,EACnBC,MAAc,EACdC,SAAmB,EACF;QACjB,MAAMC,OAAO7G,WAAW;QACxB,MAAM8G,gBAAoC;YACxC/D,IAAI8D;YACJJ;YACAC;YACAnG,SAAS,EAAE;YACXqC,UAAU;gBACR+D;gBACAC;gBACAG,cAAc,EAAE;gBAChBC,aAAa,IAAI/D;YACnB;QACF;QAEA,IAAI,CAACzC,cAAc,CAAC4C,GAAG,CAACyD,MAAMC;QAE9B,IAAI,CAAC1G,MAAM,CAACyB,IAAI,CAAC,CAAC,wBAAwB,EAAE4E,KAAK,EAAE,EAAEI,KAAK,CAAC,CAAC;QAC5D,IAAI,CAAC1E,IAAI,CAAC,yBAAyB2E;QAEnC,OAAOD;IACT;IAEA,MAAM/C,oBAAoBhB,KAAuB,EAAiB;QAChE,IAAI,CAAC,IAAI,CAACzC,MAAM,CAACa,mBAAmB,EAAE;QAGtC,MAAM+F,cAAc9C,MAAMC,IAAI,CAAC,IAAI,CAAC5D,cAAc,CAAC6D,MAAM,IAAIC,MAAM,CAAC,CAAC4C;YAEnE,MAAMxC,OAAO5B,MAAMF,QAAQ,CAAC8B,IAAI,IAAI,EAAE;YACtC,OAAOA,KAAKE,IAAI,CAAC,CAACC,MAChBqC,GAAGtE,QAAQ,CAACgE,SAAS,CAAChC,IAAI,CACxB,CAACuC,MACCA,IAAIC,WAAW,GAAGtC,QAAQ,CAACD,IAAIuC,WAAW,OAC1CvC,IAAIuC,WAAW,GAAGtC,QAAQ,CAACqC,IAAIC,WAAW;QAGlD;QAEA,KAAK,MAAMF,MAAMD,YAAa;YAE5BC,GAAG3G,OAAO,CAAC8G,IAAI,CAACvE;YAChBoE,GAAGtE,QAAQ,CAACoE,WAAW,GAAG,IAAI/D;YAG9B,IAAI,CAACiE,GAAGtE,QAAQ,CAACmE,YAAY,CAACjC,QAAQ,CAAChC,MAAML,OAAO,GAAG;gBACrDyE,GAAGtE,QAAQ,CAACmE,YAAY,CAACM,IAAI,CAACvE,MAAML,OAAO;YAC7C;YAEA,IAAI,CAACrC,MAAM,CAACyD,KAAK,CAAC,CAAC,uBAAuB,EAAEqD,GAAGnE,EAAE,CAAC,YAAY,EAAED,MAAMC,EAAE,EAAE;QAC5E;IACF;IAEA,MAAMuE,gBACJrD,KAAa,EACb0C,MAAe,EACfC,SAAoB,EACS;QAC7B,MAAMW,aAAiC,EAAE;QAGzC,KAAK,MAAML,MAAM,IAAI,CAAC1G,cAAc,CAAC6D,MAAM,GAAI;YAC7C,IAAIsC,UAAUO,GAAGtE,QAAQ,CAAC+D,MAAM,KAAKA,QAAQ;YAE7C,IAAIC,aAAa,CAACA,UAAUhC,IAAI,CAAC,CAACuC,MAAQD,GAAGtE,QAAQ,CAACgE,SAAS,CAAC9B,QAAQ,CAACqC,OAAO;gBAC9E;YACF;YAEAI,WAAWF,IAAI,IAAIH,GAAG3G,OAAO;QAC/B;QAGA,MAAMiH,aAAavD,MAAMmD,WAAW;QACpC,MAAMlD,UAAUqD,WAAWjD,MAAM,CAAC,CAACxB;YACjC,MAAM2E,aAAa/D,KAAKC,SAAS,CAACb,MAAMH,OAAO,EAAEyE,WAAW;YAC5D,OAAOK,WAAW3C,QAAQ,CAAC0C;QAC7B;QAEA,OAAOtD,QAAQoB,KAAK,CAAC,GAAG;IAC1B;IAEA,MAAMoC,uBAAuBjF,OAAe,EAKzC;QACD,MAAMkF,gBAAgB,IAAI,CAAClH,aAAa,CAAC8C,GAAG,CAACd,YAAY,IAAIa;QAC7D,MAAMsE,eAAezD,MAAMC,IAAI,CAACuD,eAC7BE,GAAG,CAAC,CAAC9E,KAAO,IAAI,CAACxC,OAAO,CAACgD,GAAG,CAACR,KAC7BuB,MAAM,CAACwD;QAEV,MAAMC,gBAAgBH,aACnB3C,IAAI,CAAC,CAACC,GAAGC,IAAMA,EAAEnC,SAAS,CAACoC,OAAO,KAAKF,EAAElC,SAAS,CAACoC,OAAO,IAC1DE,KAAK,CAAC,GAAG;QAEZ,MAAM0C,yBAAyBJ,aAAatD,MAAM,CAAC,CAACC,IAAMA,EAAE7B,IAAI,KAAK,aAAaiC,MAAM;QAExF,MAAMsD,gBAAgBL,aAAatD,MAAM,CACvC,CAACC,IAAMA,EAAE3B,QAAQ,CAACM,UAAU,KAAK,YAAYqB,EAAE3B,QAAQ,CAACM,UAAU,KAAK,QACvEyB,MAAM;QAER,OAAO;YACLuD,cAAcN,aAAajD,MAAM;YACjCoD;YACAC;YACAC;QACF;IACF;IAEA,MAAcjG,kBAAiC;QAC7C,IAAI;YAEF,MAAMmG,cAAcjI,KAAKkI,IAAI,CAAC,IAAI,CAAC/H,MAAM,CAACe,eAAe,EAAE;YAC3D,IAAI;gBACF,MAAMiH,cAAc,MAAMpI,GAAGqI,QAAQ,CAACH,aAAa;gBACnD,MAAMI,eAAe7E,KAAK8E,KAAK,CAACH;gBAEhC,KAAK,MAAMvF,SAASyF,aAAc;oBAChC,IAAI,CAAChI,OAAO,CAAC6C,GAAG,CAACN,MAAMC,EAAE,EAAE;wBACzB,GAAGD,KAAK;wBACRE,WAAW,IAAIC,KAAKH,MAAME,SAAS;oBACrC;oBAGA,IAAI,CAAC,IAAI,CAACvC,aAAa,CAAC4C,GAAG,CAACP,MAAML,OAAO,GAAG;wBAC1C,IAAI,CAAChC,aAAa,CAAC2C,GAAG,CAACN,MAAML,OAAO,EAAE,IAAIa;oBAC5C;oBACA,IAAI,CAAC7C,aAAa,CAAC8C,GAAG,CAACT,MAAML,OAAO,EAAGe,GAAG,CAACV,MAAMC,EAAE;gBACrD;gBAEA,IAAI,CAAC3C,MAAM,CAACyB,IAAI,CAAC,CAAC,OAAO,EAAE0G,aAAa5D,MAAM,CAAC,eAAe,CAAC;YACjE,EAAE,OAAO2B,OAAO;gBACd,IAAI,CAAClG,MAAM,CAACmG,IAAI,CAAC;YACnB;YAGA,MAAMkC,SAASvI,KAAKkI,IAAI,CAAC,IAAI,CAAC/H,MAAM,CAACe,eAAe,EAAE;YACtD,IAAI;gBACF,MAAMsH,SAAS,MAAMzI,GAAGqI,QAAQ,CAACG,QAAQ;gBACzC,MAAME,UAAUjF,KAAK8E,KAAK,CAACE;gBAE3B,KAAK,MAAMxB,MAAMyB,QAAS;oBACxB,IAAI,CAACnI,cAAc,CAAC4C,GAAG,CAAC8D,GAAGnE,EAAE,EAAE;wBAC7B,GAAGmE,EAAE;wBACLtE,UAAU;4BACR,GAAGsE,GAAGtE,QAAQ;4BACdoE,aAAa,IAAI/D,KAAKiE,GAAGtE,QAAQ,CAACoE,WAAW;wBAC/C;wBACAzG,SAAS2G,GAAG3G,OAAO,CAACsH,GAAG,CAAC,CAACtD,IAAY,CAAA;gCACnC,GAAGA,CAAC;gCACJvB,WAAW,IAAIC,KAAKsB,EAAEvB,SAAS;4BACjC,CAAA;oBACF;gBACF;gBAEA,IAAI,CAAC5C,MAAM,CAACyB,IAAI,CAAC,CAAC,OAAO,EAAE8G,QAAQhE,MAAM,CAAC,gBAAgB,CAAC;YAC7D,EAAE,OAAO2B,OAAO;gBACd,IAAI,CAAClG,MAAM,CAACmG,IAAI,CAAC;YACnB;QACF,EAAE,OAAOD,OAAO;YACd,IAAI,CAAClG,MAAM,CAACkG,KAAK,CAAC,+BAA+BA;QACnD;IACF;IAEA,MAAc/D,kBAAiC;QAC7C,IAAI;YAEF,MAAMgG,eAAepE,MAAMC,IAAI,CAAC,IAAI,CAAC7D,OAAO,CAAC8D,MAAM;YACnD,MAAM8D,cAAcjI,KAAKkI,IAAI,CAAC,IAAI,CAAC/H,MAAM,CAACe,eAAe,EAAE;YAC3D,MAAMnB,GAAG2I,SAAS,CAACT,aAAazE,KAAKC,SAAS,CAAC4E,cAAc,MAAM;YAGnE,MAAMI,UAAUxE,MAAMC,IAAI,CAAC,IAAI,CAAC5D,cAAc,CAAC6D,MAAM;YACrD,MAAMoE,SAASvI,KAAKkI,IAAI,CAAC,IAAI,CAAC/H,MAAM,CAACe,eAAe,EAAE;YACtD,MAAMnB,GAAG2I,SAAS,CAACH,QAAQ/E,KAAKC,SAAS,CAACgF,SAAS,MAAM;YAEzD,IAAI,CAACvI,MAAM,CAACyD,KAAK,CAAC;QACpB,EAAE,OAAOyC,OAAO;YACd,IAAI,CAAClG,MAAM,CAACkG,KAAK,CAAC,8BAA8BA;QAClD;IACF;IAEA,MAAcpE,kBAAiC;QAC7C,IAAI;YACF,MAAM,IAAI,CAACK,eAAe;YAC1B,IAAI,CAACJ,IAAI,CAAC;QACZ,EAAE,OAAOmE,OAAO;YACd,IAAI,CAAClG,MAAM,CAACkG,KAAK,CAAC,+BAA+BA;QACnD;IACF;IAEA,MAAcvC,sBAAqC;QACjD,IAAI,IAAI,CAACxD,OAAO,CAACsI,IAAI,IAAI,IAAI,CAACxI,MAAM,CAACW,UAAU,EAAE;QAEjD,IAAI,CAACZ,MAAM,CAACyB,IAAI,CAAC;QAGjB,MAAMtB,UAAU4D,MAAMC,IAAI,CAAC,IAAI,CAAC7D,OAAO,CAAC8D,MAAM,IAC3CC,MAAM,CAAC,CAACC,IAAM,AAACA,CAAAA,EAAE3B,QAAQ,CAACO,QAAQ,IAAI,CAAA,KAAM,GAC5C8B,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAElC,SAAS,CAACoC,OAAO,KAAKD,EAAEnC,SAAS,CAACoC,OAAO;QAE7D,MAAM0D,WAAWvI,QAAQ+E,KAAK,CAAC,GAAG,IAAI,CAAC/E,OAAO,CAACsI,IAAI,GAAG,IAAI,CAACxI,MAAM,CAACW,UAAU;QAE5E,KAAK,MAAM8B,SAASgG,SAAU;YAC5B,IAAI,CAACvI,OAAO,CAACwI,MAAM,CAACjG,MAAMC,EAAE;YAG5B,MAAM6E,eAAe,IAAI,CAACnH,aAAa,CAAC8C,GAAG,CAACT,MAAML,OAAO;YACzD,IAAImF,cAAc;gBAChBA,aAAamB,MAAM,CAACjG,MAAMC,EAAE;YAC9B;YAEA,IAAI,CAAC3C,MAAM,CAACyD,KAAK,CAAC,CAAC,0BAA0B,EAAEf,MAAMC,EAAE,EAAE;QAC3D;QAEA,IAAI,CAACZ,IAAI,CAAC,kBAAkB2G,SAASnE,MAAM;IAC7C;IAGAqE,iBAME;QACA,MAAMzI,UAAU4D,MAAMC,IAAI,CAAC,IAAI,CAAC7D,OAAO,CAAC8D,MAAM;QAC9C,MAAM4E,gBAAwC,CAAC;QAC/C,MAAMC,iBAAyC,CAAC;QAEhD,KAAK,MAAMpG,SAASvC,QAAS;YAC3B0I,aAAa,CAACnG,MAAMJ,IAAI,CAAC,GAAG,AAACuG,CAAAA,aAAa,CAACnG,MAAMJ,IAAI,CAAC,IAAI,CAAA,IAAK;YAC/DwG,cAAc,CAACpG,MAAML,OAAO,CAAC,GAAG,AAACyG,CAAAA,cAAc,CAACpG,MAAML,OAAO,CAAC,IAAI,CAAA,IAAK;QACzE;QAGA,MAAM0G,cAAczF,KAAKC,SAAS,CAACpD,SAASoE,MAAM;QAElD,OAAO;YACLuD,cAAc3H,QAAQoE,MAAM;YAC5BsE;YACAC;YACA1I,gBAAgB,IAAI,CAACA,cAAc,CAACqI,IAAI;YACxCM;QACF;IACF;IAEA,MAAMC,aAAa3G,OAAgB,EAAgB;QACjD,MAAMlC,UAAUkC,UAAU,MAAM,IAAI,CAACuB,MAAM,CAAC;YAAEvB;QAAQ,KAAK0B,MAAMC,IAAI,CAAC,IAAI,CAAC7D,OAAO,CAAC8D,MAAM;QAEzF,OAAO;YACL9D;YACAC,gBAAgBiC,UACZ0B,MAAMC,IAAI,CAAC,IAAI,CAAC5D,cAAc,CAAC6D,MAAM,IAAIC,MAAM,CAAC,CAAC4C,KAC/CA,GAAGtE,QAAQ,CAACmE,YAAY,CAACjC,QAAQ,CAACrC,YAEpC0B,MAAMC,IAAI,CAAC,IAAI,CAAC5D,cAAc,CAAC6D,MAAM;YACzCgF,YAAY,IAAIpG;YAChBqG,OAAO,IAAI,CAACN,cAAc;QAC5B;IACF;IAEA,MAAMO,YAAY9G,OAAgB,EAAiB;QACjD,IAAIA,SAAS;YAEX,MAAM+G,WAAW,IAAI,CAAC/I,aAAa,CAAC8C,GAAG,CAACd,YAAY,IAAIa;YACxD,KAAK,MAAMT,WAAW2G,SAAU;gBAC9B,IAAI,CAACjJ,OAAO,CAACwI,MAAM,CAAClG;YACtB;YACA,IAAI,CAACpC,aAAa,CAACsI,MAAM,CAACtG;YAC1B,IAAI,CAACrC,MAAM,CAACyB,IAAI,CAAC,CAAC,yBAAyB,EAAEY,SAAS;QACxD,OAAO;YAEL,IAAI,CAAClC,OAAO,CAACkJ,KAAK;YAClB,IAAI,CAAChJ,aAAa,CAACgJ,KAAK;YACxB,IAAI,CAACjJ,cAAc,CAACiJ,KAAK;YACzB,IAAI,CAACrJ,MAAM,CAACyB,IAAI,CAAC;QACnB;QAEA,IAAI,CAACM,IAAI,CAAC,kBAAkB;YAAEM;QAAQ;IACxC;IAGA,MAAMiH,MAAMjG,GAAW,EAAEkG,KAAU,EAAiB;QAElD,MAAMC,QAAQnG,IAAIoG,KAAK,CAAC;QACxB,MAAMnH,OAAO,AAACkH,KAAK,CAAC,EAAE,IAAiC;QACvD,MAAMnH,UAAUmH,KAAK,CAAC,EAAE,IAAI;QAE5B,MAAM,IAAI,CAACpH,QAAQ,CAACC,SAASC,MAAMiH,OAAO;YACxCjF,MAAM;gBAACkF,KAAK,CAAC,EAAE;gBAAEA,KAAK,CAAC,EAAE;aAAC,CAACtF,MAAM,CAACwD;YAClC5E,YAAY;QACd;IACF;IAEA,MAAM4G,OAAOC,OAAe,EAAE1E,QAAgB,EAAE,EAAkB;QAEhE,MAAMnB,UAAiB,EAAE;QAEzB,KAAK,MAAMpB,SAAS,IAAI,CAACvC,OAAO,CAAC8D,MAAM,GAAI;YACzC,MAAM2F,cAActG,KAAKC,SAAS,CAACb;YACnC,IAAIkH,YAAYlF,QAAQ,CAACiF,QAAQE,OAAO,CAAC,KAAK,MAAM;gBAClD/F,QAAQmD,IAAI,CAACvE,MAAMH,OAAO;gBAC1B,IAAIuB,QAAQS,MAAM,IAAIU,OAAO;YAC/B;QACF;QAEA,OAAOnB;IACT;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../src/memory/swarm-memory.js"],"sourcesContent":["/**\n * SwarmMemory - MCP-specific memory persistence extending SharedMemory\n * Provides swarm-specific features like agent coordination, task tracking, and neural patterns\n *\n * @module swarm-memory\n */\n\nimport { SharedMemory } from './shared-memory.js';\nimport path from 'path';\n\n/**\n * Swarm-specific namespaces\n */\nconst SWARM_NAMESPACES = {\n AGENTS: 'swarm:agents',\n TASKS: 'swarm:tasks',\n COMMUNICATIONS: 'swarm:communications',\n CONSENSUS: 'swarm:consensus',\n PATTERNS: 'swarm:patterns',\n METRICS: 'swarm:metrics',\n COORDINATION: 'swarm:coordination',\n};\n\n/**\n * SwarmMemory class - Extends SharedMemory with MCP features\n */\nexport class SwarmMemory extends SharedMemory {\n constructor(options = {}) {\n // Default to .swarm directory for MCP\n super({\n directory: options.directory || '.swarm',\n filename: options.filename || 'swarm-memory.db',\n ...options,\n });\n\n this.swarmId = options.swarmId || 'default';\n this.mcpMode = options.mcpMode !== false;\n\n // Additional swarm-specific caches\n this.agentCache = new Map();\n this.taskCache = new Map();\n this.patternCache = new Map();\n }\n\n /**\n * Initialize with swarm-specific setup\n */\n async initialize() {\n await super.initialize();\n\n // Initialize swarm-specific namespaces\n await this._initializeSwarmNamespaces();\n\n // Load active agents and tasks into cache\n await this._loadSwarmState();\n\n this.emit('swarm:initialized', { swarmId: this.swarmId });\n }\n\n /**\n * Store agent information\n */\n async storeAgent(agentId, agentData) {\n const key = `agent:${agentId}`;\n const enrichedData = {\n ...agentData,\n swarmId: this.swarmId,\n lastUpdated: new Date().toISOString(),\n };\n\n await this.store(key, enrichedData, {\n namespace: SWARM_NAMESPACES.AGENTS,\n tags: ['agent', agentData.type, agentData.status],\n metadata: {\n swarmId: this.swarmId,\n agentType: agentData.type,\n },\n });\n\n // Update agent cache\n this.agentCache.set(agentId, enrichedData);\n\n this.emit('swarm:agentStored', { agentId, type: agentData.type });\n\n return { agentId, stored: true };\n }\n\n /**\n * Retrieve agent information\n */\n async getAgent(agentId) {\n // Check cache first\n if (this.agentCache.has(agentId)) {\n return this.agentCache.get(agentId);\n }\n\n const key = `agent:${agentId}`;\n const agent = await this.retrieve(key, SWARM_NAMESPACES.AGENTS);\n\n if (agent) {\n this.agentCache.set(agentId, agent);\n }\n\n return agent;\n }\n\n /**\n * List all agents in swarm\n */\n async listAgents(filter = {}) {\n const agents = await this.list(SWARM_NAMESPACES.AGENTS, {\n limit: filter.limit || 100,\n });\n\n return agents\n .map((entry) => entry.value)\n .filter((agent) => {\n if (filter.type && agent.type !== filter.type) return false;\n if (filter.status && agent.status !== filter.status) return false;\n if (filter.swarmId && agent.swarmId !== filter.swarmId) return false;\n return true;\n });\n }\n\n /**\n * Store task information\n */\n async storeTask(taskId, taskData) {\n const key = `task:${taskId}`;\n const enrichedData = {\n ...taskData,\n swarmId: this.swarmId,\n createdAt: taskData.createdAt || new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n\n await this.store(key, enrichedData, {\n namespace: SWARM_NAMESPACES.TASKS,\n tags: ['task', taskData.status, taskData.priority],\n metadata: {\n swarmId: this.swarmId,\n assignedAgents: taskData.assignedAgents || [],\n },\n });\n\n // Update task cache\n this.taskCache.set(taskId, enrichedData);\n\n this.emit('swarm:taskStored', { taskId, status: taskData.status });\n\n return { taskId, stored: true };\n }\n\n /**\n * Update task status\n */\n async updateTaskStatus(taskId, status, result = null) {\n const task = await this.getTask(taskId);\n if (!task) {\n throw new Error(`Task ${taskId} not found`);\n }\n\n task.status = status;\n task.updatedAt = new Date().toISOString();\n\n if (result) {\n task.result = result;\n }\n\n if (status === 'completed') {\n task.completedAt = new Date().toISOString();\n }\n\n await this.storeTask(taskId, task);\n\n this.emit('swarm:taskStatusUpdated', { taskId, status });\n\n return { taskId, status, updated: true };\n }\n\n /**\n * Get task information\n */\n async getTask(taskId) {\n // Check cache first\n if (this.taskCache.has(taskId)) {\n return this.taskCache.get(taskId);\n }\n\n const key = `task:${taskId}`;\n const task = await this.retrieve(key, SWARM_NAMESPACES.TASKS);\n\n if (task) {\n this.taskCache.set(taskId, task);\n }\n\n return task;\n }\n\n /**\n * Store inter-agent communication\n */\n async storeCommunication(fromAgent, toAgent, message) {\n const commId = `comm:${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const communication = {\n id: commId,\n fromAgent,\n toAgent,\n message,\n swarmId: this.swarmId,\n timestamp: new Date().toISOString(),\n };\n\n await this.store(commId, communication, {\n namespace: SWARM_NAMESPACES.COMMUNICATIONS,\n ttl: 86400, // 24 hours\n tags: ['communication', message.type],\n metadata: {\n fromAgent,\n toAgent,\n messageType: message.type,\n },\n });\n\n this.emit('swarm:communication', { fromAgent, toAgent, type: message.type });\n\n return { id: commId, stored: true };\n }\n\n /**\n * Store consensus decision\n */\n async storeConsensus(consensusId, decision) {\n const key = `consensus:${consensusId}`;\n const consensusData = {\n ...decision,\n swarmId: this.swarmId,\n timestamp: new Date().toISOString(),\n };\n\n await this.store(key, consensusData, {\n namespace: SWARM_NAMESPACES.CONSENSUS,\n tags: ['consensus', decision.status],\n metadata: {\n swarmId: this.swarmId,\n taskId: decision.taskId,\n threshold: decision.threshold,\n },\n });\n\n this.emit('swarm:consensus', { consensusId, status: decision.status });\n\n return { consensusId, stored: true };\n }\n\n /**\n * Store neural pattern\n */\n async storePattern(patternId, pattern) {\n const key = `pattern:${patternId}`;\n const patternData = {\n ...pattern,\n swarmId: this.swarmId,\n createdAt: new Date().toISOString(),\n usageCount: 0,\n successRate: 0,\n };\n\n await this.store(key, patternData, {\n namespace: SWARM_NAMESPACES.PATTERNS,\n tags: ['pattern', pattern.type],\n metadata: {\n swarmId: this.swarmId,\n patternType: pattern.type,\n confidence: pattern.confidence || 0,\n },\n });\n\n // Cache frequently used patterns\n if (pattern.type === 'coordination' || pattern.type === 'optimization') {\n this.patternCache.set(patternId, patternData);\n }\n\n this.emit('swarm:patternStored', { patternId, type: pattern.type });\n\n return { patternId, stored: true };\n }\n\n /**\n * Update pattern usage and success metrics\n */\n async updatePatternMetrics(patternId, success = true) {\n const pattern = await this.getPattern(patternId);\n if (!pattern) {\n throw new Error(`Pattern ${patternId} not found`);\n }\n\n pattern.usageCount++;\n pattern.lastUsedAt = new Date().toISOString();\n\n // Update success rate with exponential moving average\n const alpha = 0.1; // Smoothing factor\n const currentSuccess = success ? 1 : 0;\n pattern.successRate = alpha * currentSuccess + (1 - alpha) * (pattern.successRate || 0);\n\n await this.storePattern(patternId, pattern);\n\n return { patternId, usageCount: pattern.usageCount, successRate: pattern.successRate };\n }\n\n /**\n * Get pattern\n */\n async getPattern(patternId) {\n // Check cache first\n if (this.patternCache.has(patternId)) {\n return this.patternCache.get(patternId);\n }\n\n const key = `pattern:${patternId}`;\n return await this.retrieve(key, SWARM_NAMESPACES.PATTERNS);\n }\n\n /**\n * Find best patterns for a given context\n */\n async findBestPatterns(context, limit = 5) {\n const patterns = await this.search({\n namespace: SWARM_NAMESPACES.PATTERNS,\n tags: context.tags,\n limit: 100,\n });\n\n // Score patterns based on success rate and relevance\n const scored = patterns.map((entry) => {\n const pattern = entry.value;\n const score =\n pattern.successRate * 0.7 +\n (pattern.confidence || 0) * 0.2 +\n (pattern.usageCount > 0 ? 0.1 : 0);\n\n return { ...pattern, score };\n });\n\n // Sort by score and return top patterns\n return scored.sort((a, b) => b.score - a.score).slice(0, limit);\n }\n\n /**\n * Store coordination state\n */\n async storeCoordination(key, state) {\n await this.store(key, state, {\n namespace: SWARM_NAMESPACES.COORDINATION,\n ttl: 3600, // 1 hour\n metadata: {\n swarmId: this.swarmId,\n timestamp: new Date().toISOString(),\n },\n });\n\n return { key, stored: true };\n }\n\n /**\n * Get coordination state\n */\n async getCoordination(key) {\n return await this.retrieve(key, SWARM_NAMESPACES.COORDINATION);\n }\n\n /**\n * Store performance metrics\n */\n async storeMetrics(metricsId, metrics) {\n const key = `metrics:${metricsId}`;\n await this.store(key, metrics, {\n namespace: SWARM_NAMESPACES.METRICS,\n ttl: 86400 * 7, // 7 days\n tags: ['metrics', metrics.type],\n metadata: {\n swarmId: this.swarmId,\n agentId: metrics.agentId,\n timestamp: new Date().toISOString(),\n },\n });\n\n this.emit('swarm:metricsStored', { metricsId, type: metrics.type });\n\n return { metricsId, stored: true };\n }\n\n /**\n * Get swarm statistics\n */\n async getSwarmStats() {\n const baseStats = await this.getStats();\n\n // Add swarm-specific stats\n const agentCount = await this._countNamespace(SWARM_NAMESPACES.AGENTS);\n const taskCount = await this._countNamespace(SWARM_NAMESPACES.TASKS);\n const patternCount = await this._countNamespace(SWARM_NAMESPACES.PATTERNS);\n\n // Get active agents\n const activeAgents = Array.from(this.agentCache.values()).filter(\n (agent) => agent.status === 'active' || agent.status === 'busy',\n ).length;\n\n // Get task statistics\n const tasks = Array.from(this.taskCache.values());\n const taskStats = {\n total: tasks.length,\n pending: tasks.filter((t) => t.status === 'pending').length,\n inProgress: tasks.filter((t) => t.status === 'in_progress').length,\n completed: tasks.filter((t) => t.status === 'completed').length,\n failed: tasks.filter((t) => t.status === 'failed').length,\n };\n\n return {\n ...baseStats,\n swarm: {\n swarmId: this.swarmId,\n agents: {\n total: agentCount,\n active: activeAgents,\n cached: this.agentCache.size,\n },\n tasks: taskStats,\n patterns: {\n total: patternCount,\n cached: this.patternCache.size,\n },\n namespaces: Object.values(SWARM_NAMESPACES),\n },\n };\n }\n\n /**\n * Clean up old swarm data\n */\n async cleanupSwarmData(options = {}) {\n const {\n maxAge = 86400 * 7, // 7 days\n keepPatterns = true,\n keepConsensus = true,\n } = options;\n\n const cutoffTime = Date.now() - maxAge * 1000;\n let cleaned = 0;\n\n // Clean old communications\n const comms = await this.list(SWARM_NAMESPACES.COMMUNICATIONS);\n for (const comm of comms) {\n if (new Date(comm.value.timestamp).getTime() < cutoffTime) {\n await this.delete(comm.key, SWARM_NAMESPACES.COMMUNICATIONS);\n cleaned++;\n }\n }\n\n // Clean completed tasks\n const tasks = await this.list(SWARM_NAMESPACES.TASKS);\n for (const task of tasks) {\n if (\n task.value.status === 'completed' &&\n new Date(task.value.completedAt).getTime() < cutoffTime\n ) {\n await this.delete(task.key, SWARM_NAMESPACES.TASKS);\n this.taskCache.delete(task.value.id);\n cleaned++;\n }\n }\n\n // Clean old metrics\n const metrics = await this.list(SWARM_NAMESPACES.METRICS);\n for (const metric of metrics) {\n if (new Date(metric.createdAt).getTime() < cutoffTime) {\n await this.delete(metric.key, SWARM_NAMESPACES.METRICS);\n cleaned++;\n }\n }\n\n this.emit('swarm:cleanup', { cleaned, maxAge });\n\n return { cleaned };\n }\n\n /**\n * Export swarm state\n */\n async exportSwarmState() {\n const agents = await this.listAgents();\n const tasks = Array.from(this.taskCache.values());\n const patterns = await this.list(SWARM_NAMESPACES.PATTERNS);\n\n return {\n swarmId: this.swarmId,\n exportedAt: new Date().toISOString(),\n agents: agents,\n tasks: tasks,\n patterns: patterns.map((p) => p.value),\n statistics: await this.getSwarmStats(),\n };\n }\n\n /**\n * Import swarm state\n */\n async importSwarmState(state) {\n let imported = {\n agents: 0,\n tasks: 0,\n patterns: 0,\n };\n\n // Import agents\n if (state.agents) {\n for (const agent of state.agents) {\n await this.storeAgent(agent.id, agent);\n imported.agents++;\n }\n }\n\n // Import tasks\n if (state.tasks) {\n for (const task of state.tasks) {\n await this.storeTask(task.id, task);\n imported.tasks++;\n }\n }\n\n // Import patterns\n if (state.patterns) {\n for (const pattern of state.patterns) {\n await this.storePattern(pattern.id, pattern);\n imported.patterns++;\n }\n }\n\n this.emit('swarm:imported', imported);\n\n return imported;\n }\n\n /**\n * Private helper methods\n */\n\n async _initializeSwarmNamespaces() {\n // Create swarm metadata\n await this.store(\n 'swarm:metadata',\n {\n swarmId: this.swarmId,\n createdAt: new Date().toISOString(),\n version: '1.0.0',\n namespaces: Object.values(SWARM_NAMESPACES),\n },\n {\n namespace: 'swarm:system',\n },\n );\n }\n\n async _loadSwarmState() {\n // Load active agents\n const agents = await this.list(SWARM_NAMESPACES.AGENTS, { limit: 100 });\n for (const entry of agents) {\n if (entry.value.status === 'active' || entry.value.status === 'busy') {\n this.agentCache.set(entry.value.id, entry.value);\n }\n }\n\n // Load in-progress tasks\n const tasks = await this.search({\n namespace: SWARM_NAMESPACES.TASKS,\n tags: ['in_progress'],\n limit: 100,\n });\n for (const entry of tasks) {\n this.taskCache.set(entry.value.id, entry.value);\n }\n\n // Load high-confidence patterns\n const patterns = await this.list(SWARM_NAMESPACES.PATTERNS, { limit: 50 });\n for (const entry of patterns) {\n if (entry.value.confidence > 0.7 || entry.value.successRate > 0.8) {\n this.patternCache.set(entry.value.id, entry.value);\n }\n }\n }\n\n async _countNamespace(namespace) {\n const stats = await this.getStats();\n return stats.namespaces[namespace]?.count || 0;\n }\n}\n\n// Export factory function for easy creation\nexport function createSwarmMemory(options = {}) {\n return new SwarmMemory(options);\n}\n\n// Export for backwards compatibility\nexport default SwarmMemory;\n"],"names":["SharedMemory","SWARM_NAMESPACES","AGENTS","TASKS","COMMUNICATIONS","CONSENSUS","PATTERNS","METRICS","COORDINATION","SwarmMemory","options","directory","filename","swarmId","mcpMode","agentCache","Map","taskCache","patternCache","initialize","_initializeSwarmNamespaces","_loadSwarmState","emit","storeAgent","agentId","agentData","key","enrichedData","lastUpdated","Date","toISOString","store","namespace","tags","type","status","metadata","agentType","set","stored","getAgent","has","get","agent","retrieve","listAgents","filter","agents","list","limit","map","entry","value","storeTask","taskId","taskData","createdAt","updatedAt","priority","assignedAgents","updateTaskStatus","result","task","getTask","Error","completedAt","updated","storeCommunication","fromAgent","toAgent","message","commId","now","Math","random","toString","substr","communication","id","timestamp","ttl","messageType","storeConsensus","consensusId","decision","consensusData","threshold","storePattern","patternId","pattern","patternData","usageCount","successRate","patternType","confidence","updatePatternMetrics","success","getPattern","lastUsedAt","alpha","currentSuccess","findBestPatterns","context","patterns","search","scored","score","sort","a","b","slice","storeCoordination","state","getCoordination","storeMetrics","metricsId","metrics","getSwarmStats","baseStats","getStats","agentCount","_countNamespace","taskCount","patternCount","activeAgents","Array","from","values","length","tasks","taskStats","total","pending","t","inProgress","completed","failed","swarm","active","cached","size","namespaces","Object","cleanupSwarmData","maxAge","keepPatterns","keepConsensus","cutoffTime","cleaned","comms","comm","getTime","delete","metric","exportSwarmState","exportedAt","p","statistics","importSwarmState","imported","version","stats","count","createSwarmMemory"],"mappings":"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"}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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/key-redactor.
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/key-redactor.ts"],"sourcesContent":["/**\n * API Key Redaction Utility\n * Prevents sensitive data from leaking into logs, memory, or git commits\n */\n\nexport interface RedactionConfig {\n patterns: RegExp[];\n replacement: string;\n maskLength: number;\n}\n\nexport class KeyRedactor {\n private static readonly API_KEY_PATTERNS = [\n // Anthropic API keys\n /sk-ant-[a-zA-Z0-9_-]{95,}/gi,\n\n // OpenRouter API keys\n /sk-or-[a-zA-Z0-9_-]{32,}/gi,\n\n // Google/Gemini API keys\n /AIza[a-zA-Z0-9_-]{35}/gi,\n\n // Generic API keys\n /[a-zA-Z0-9_-]{20,}API[a-zA-Z0-9_-]{20,}/gi,\n\n // Bearer tokens\n /Bearer\\s+[a-zA-Z0-9_\\-\\.]{20,}/gi,\n\n // Environment variable format\n /([A-Z_]+_API_KEY|[A-Z_]+_TOKEN|[A-Z_]+_SECRET)=[\"']?([^\"'\\s]+)[\"']?/gi,\n\n // Supabase keys\n /eyJ[a-zA-Z0-9_-]*\\.eyJ[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]*/gi,\n ];\n\n private static readonly SENSITIVE_FIELDS = [\n 'apiKey',\n 'api_key',\n 'token',\n 'secret',\n 'password',\n 'private_key',\n 'privateKey',\n 'accessToken',\n 'access_token',\n 'refreshToken',\n 'refresh_token',\n ];\n\n /**\n * Redact API keys and sensitive data from text\n */\n static redact(text: string, showPrefix = true): string {\n if (!text) return text;\n\n let redacted = text;\n\n // Redact using patterns\n this.API_KEY_PATTERNS.forEach(pattern => {\n redacted = redacted.replace(pattern, (match) => {\n if (showPrefix && match.length > 8) {\n const prefix = match.substring(0, 8);\n return `${prefix}...[REDACTED]`;\n }\n return '[REDACTED_API_KEY]';\n });\n });\n\n return redacted;\n }\n\n /**\n * Redact sensitive fields in objects\n */\n static redactObject<T extends Record<string, any>>(obj: T, deep = true): T {\n if (!obj || typeof obj !== 'object') return obj;\n\n const redacted = { ...obj };\n\n Object.keys(redacted).forEach(key => {\n const lowerKey = key.toLowerCase();\n\n // Check if field name is sensitive\n const isSensitive = this.SENSITIVE_FIELDS.some(field =>\n lowerKey.includes(field)\n );\n\n if (isSensitive && typeof redacted[key] === 'string') {\n const value = redacted[key] as string;\n if (value && value.length > 8) {\n redacted[key] = `${value.substring(0, 4)}...[REDACTED]` as any;\n } else {\n redacted[key] = '[REDACTED]' as any;\n }\n } else if (deep && typeof redacted[key] === 'object' && redacted[key] !== null) {\n redacted[key] = this.redactObject(redacted[key], deep);\n } else if (typeof redacted[key] === 'string') {\n // Redact any API keys in string values\n redacted[key] = this.redact(redacted[key]) as any;\n }\n });\n\n return redacted;\n }\n\n /**\n * Sanitize text for safe logging\n */\n static sanitize(text: string): string {\n return this.redact(text, true);\n }\n\n /**\n * Sanitize command arguments\n */\n static sanitizeArgs(args: string[]): string[] {\n return args.map(arg => {\n // Check if arg is a flag value pair\n if (arg.includes('key') || arg.includes('token') || arg.includes('secret')) {\n return this.redact(arg);\n }\n return arg;\n });\n }\n\n /**\n * Check if text contains unredacted sensitive data\n */\n static containsSensitiveData(text: string): boolean {\n return this.API_KEY_PATTERNS.some(pattern => pattern.test(text));\n }\n\n /**\n * Validate that text is safe for logging/storage\n */\n static validate(text: string): { safe: boolean; warnings: string[] } {\n const warnings: string[] = [];\n\n this.API_KEY_PATTERNS.forEach((pattern, index) => {\n if (pattern.test(text)) {\n warnings.push(`Potential API key detected (pattern ${index + 1})`);\n }\n });\n\n return {\n safe: warnings.length === 0,\n warnings,\n };\n }\n\n /**\n * Redact environment variables\n */\n static redactEnv(env: Record<string, string | undefined>): Record<string, string> {\n const redacted: Record<string, string> = {};\n\n Object.keys(env).forEach(key => {\n const value = env[key];\n if (!value) {\n redacted[key] = '';\n return;\n }\n\n const lowerKey = key.toLowerCase();\n const isSensitive = lowerKey.includes('key') ||\n lowerKey.includes('token') ||\n lowerKey.includes('secret') ||\n lowerKey.includes('password');\n\n if (isSensitive) {\n redacted[key] = value.length > 8\n ? `${value.substring(0, 4)}...[REDACTED]`\n : '[REDACTED]';\n } else {\n redacted[key] = value;\n }\n });\n\n return redacted;\n }\n}\n\n// Export singleton instance\nexport const redactor = KeyRedactor;\n"],"names":["KeyRedactor","API_KEY_PATTERNS","SENSITIVE_FIELDS","redact","text","showPrefix","redacted","forEach","pattern","replace","match","length","prefix","substring","redactObject","obj","deep","Object","keys","key","lowerKey","toLowerCase","isSensitive","some","field","includes","value","sanitize","sanitizeArgs","args","map","arg","containsSensitiveData","test","validate","warnings","index","push","safe","redactEnv","env","redactor"],"mappings":"AAWA,OAAO,MAAMA;IACX,OAAwBC,mBAAmB;QAEzC;QAGA;QAGA;QAGA;QAGA;QAGA;QAGA;KACD,CAAC;IAEF,OAAwBC,mBAAmB;QACzC;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;KACD,CAAC;IAKF,OAAOC,OAAOC,IAAY,EAAEC,aAAa,IAAI,EAAU;QACrD,IAAI,CAACD,MAAM,OAAOA;QAElB,IAAIE,WAAWF;QAGf,IAAI,CAACH,gBAAgB,CAACM,OAAO,CAACC,CAAAA;YAC5BF,WAAWA,SAASG,OAAO,CAACD,SAAS,CAACE;gBACpC,IAAIL,cAAcK,MAAMC,MAAM,GAAG,GAAG;oBAClC,MAAMC,SAASF,MAAMG,SAAS,CAAC,GAAG;oBAClC,OAAO,GAAGD,OAAO,aAAa,CAAC;gBACjC;gBACA,OAAO;YACT;QACF;QAEA,OAAON;IACT;IAKA,OAAOQ,aAA4CC,GAAM,EAAEC,OAAO,IAAI,EAAK;QACzE,IAAI,CAACD,OAAO,OAAOA,QAAQ,UAAU,OAAOA;QAE5C,MAAMT,WAAW;YAAE,GAAGS,GAAG;QAAC;QAE1BE,OAAOC,IAAI,CAACZ,UAAUC,OAAO,CAACY,CAAAA;YAC5B,MAAMC,WAAWD,IAAIE,WAAW;YAGhC,MAAMC,cAAc,IAAI,CAACpB,gBAAgB,CAACqB,IAAI,CAACC,CAAAA,QAC7CJ,SAASK,QAAQ,CAACD;YAGpB,IAAIF,eAAe,OAAOhB,QAAQ,CAACa,IAAI,KAAK,UAAU;gBACpD,MAAMO,QAAQpB,QAAQ,CAACa,IAAI;gBAC3B,IAAIO,SAASA,MAAMf,MAAM,GAAG,GAAG;oBAC7BL,QAAQ,CAACa,IAAI,GAAG,GAAGO,MAAMb,SAAS,CAAC,GAAG,GAAG,aAAa,CAAC;gBACzD,OAAO;oBACLP,QAAQ,CAACa,IAAI,GAAG;gBAClB;YACF,OAAO,IAAIH,QAAQ,OAAOV,QAAQ,CAACa,IAAI,KAAK,YAAYb,QAAQ,CAACa,IAAI,KAAK,MAAM;gBAC9Eb,QAAQ,CAACa,IAAI,GAAG,IAAI,CAACL,YAAY,CAACR,QAAQ,CAACa,IAAI,EAAEH;YACnD,OAAO,IAAI,OAAOV,QAAQ,CAACa,IAAI,KAAK,UAAU;gBAE5Cb,QAAQ,CAACa,IAAI,GAAG,IAAI,CAAChB,MAAM,CAACG,QAAQ,CAACa,IAAI;YAC3C;QACF;QAEA,OAAOb;IACT;IAKA,OAAOqB,SAASvB,IAAY,EAAU;QACpC,OAAO,IAAI,CAACD,MAAM,CAACC,MAAM;IAC3B;IAKA,OAAOwB,aAAaC,IAAc,EAAY;QAC5C,OAAOA,KAAKC,GAAG,CAACC,CAAAA;YAEd,IAAIA,IAAIN,QAAQ,CAAC,UAAUM,IAAIN,QAAQ,CAAC,YAAYM,IAAIN,QAAQ,CAAC,WAAW;gBAC1E,OAAO,IAAI,CAACtB,MAAM,CAAC4B;YACrB;YACA,OAAOA;QACT;IACF;IAKA,OAAOC,sBAAsB5B,IAAY,EAAW;QAClD,OAAO,IAAI,CAACH,gBAAgB,CAACsB,IAAI,CAACf,CAAAA,UAAWA,QAAQyB,IAAI,CAAC7B;IAC5D;IAKA,OAAO8B,SAAS9B,IAAY,EAAyC;QACnE,MAAM+B,WAAqB,EAAE;QAE7B,IAAI,CAAClC,gBAAgB,CAACM,OAAO,CAAC,CAACC,SAAS4B;YACtC,IAAI5B,QAAQyB,IAAI,CAAC7B,OAAO;gBACtB+B,SAASE,IAAI,CAAC,CAAC,oCAAoC,EAAED,QAAQ,EAAE,CAAC,CAAC;YACnE;QACF;QAEA,OAAO;YACLE,MAAMH,SAASxB,MAAM,KAAK;YAC1BwB;QACF;IACF;IAKA,OAAOI,UAAUC,GAAuC,EAA0B;QAChF,MAAMlC,WAAmC,CAAC;QAE1CW,OAAOC,IAAI,CAACsB,KAAKjC,OAAO,CAACY,CAAAA;YACvB,MAAMO,QAAQc,GAAG,CAACrB,IAAI;YACtB,IAAI,CAACO,OAAO;gBACVpB,QAAQ,CAACa,IAAI,GAAG;gBAChB;YACF;YAEA,MAAMC,WAAWD,IAAIE,WAAW;YAChC,MAAMC,cAAcF,SAASK,QAAQ,CAAC,UACnBL,SAASK,QAAQ,CAAC,YAClBL,SAASK,QAAQ,CAAC,aAClBL,SAASK,QAAQ,CAAC;YAErC,IAAIH,aAAa;gBACfhB,QAAQ,CAACa,IAAI,GAAGO,MAAMf,MAAM,GAAG,IAC3B,GAAGe,MAAMb,SAAS,CAAC,GAAG,GAAG,aAAa,CAAC,GACvC;YACN,OAAO;gBACLP,QAAQ,CAACa,IAAI,GAAGO;YAClB;QACF;QAEA,OAAOpB;IACT;AACF;AAGA,OAAO,MAAMmC,WAAWzC,YAAY"}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# Bug Report: `memory stats` Command Returns Zero for ReasoningBank Data
|
|
2
|
+
|
|
3
|
+
## Executive Summary
|
|
4
|
+
|
|
5
|
+
The `memory stats` command always returns zero entries/namespaces/size, even when ReasoningBank contains data. This is caused by the command exclusively reading from the legacy JSON file (`./memory/memory-store.json`) instead of querying the active ReasoningBank SQLite database.
|
|
6
|
+
|
|
7
|
+
## Bug Details
|
|
8
|
+
|
|
9
|
+
### Issue
|
|
10
|
+
- **Command**: `npx claude-flow@alpha memory stats`
|
|
11
|
+
- **Expected**: Shows statistics for ReasoningBank database (19 entries found via direct SQL query)
|
|
12
|
+
- **Actual**: Returns all zeros (0 entries, 0 namespaces, 0.00 KB)
|
|
13
|
+
- **Severity**: High - Users cannot see their stored data statistics
|
|
14
|
+
- **Affected Versions**: v2.7.30 and likely earlier
|
|
15
|
+
|
|
16
|
+
### Evidence
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Command returns zeros
|
|
20
|
+
$ npx claude-flow@alpha memory stats
|
|
21
|
+
ā
Memory Bank Statistics:
|
|
22
|
+
Total Entries: 0
|
|
23
|
+
Namespaces: 0
|
|
24
|
+
Size: 0.00 KB
|
|
25
|
+
|
|
26
|
+
# But ReasoningBank list shows 10+ entries
|
|
27
|
+
$ npx claude-flow@alpha memory list --reasoningbank
|
|
28
|
+
ā
ReasoningBank memories (10 shown):
|
|
29
|
+
š test-key
|
|
30
|
+
š test-sqlite
|
|
31
|
+
š api-design
|
|
32
|
+
[... 16 more entries]
|
|
33
|
+
|
|
34
|
+
# Direct SQL query confirms 19 entries exist
|
|
35
|
+
$ sqlite3 .swarm/memory.db "SELECT COUNT(*) FROM patterns WHERE type = 'reasoning_memory';"
|
|
36
|
+
19
|
|
37
|
+
|
|
38
|
+
# ReasoningBank status confirms data exists
|
|
39
|
+
$ npx claude-flow@alpha memory status --reasoningbank
|
|
40
|
+
ā
š ReasoningBank Status:
|
|
41
|
+
Total memories: 19
|
|
42
|
+
Average confidence: 80.0%
|
|
43
|
+
Embeddings: 19
|
|
44
|
+
Trajectories: 0
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Root Cause Analysis
|
|
48
|
+
|
|
49
|
+
### Code Analysis (src/cli/simple-commands/memory.js)
|
|
50
|
+
|
|
51
|
+
**Problem Location**: Lines 217-244
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
async function showMemoryStats(loadMemory) {
|
|
55
|
+
try {
|
|
56
|
+
const data = await loadMemory(); // ā Only reads JSON file
|
|
57
|
+
let totalEntries = 0;
|
|
58
|
+
const namespaceStats = {};
|
|
59
|
+
|
|
60
|
+
for (const [namespace, entries] of Object.entries(data)) {
|
|
61
|
+
namespaceStats[namespace] = entries.length;
|
|
62
|
+
totalEntries += entries.length;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
printSuccess('Memory Bank Statistics:');
|
|
66
|
+
console.log(` Total Entries: ${totalEntries}`);
|
|
67
|
+
console.log(` Namespaces: ${Object.keys(data).length}`);
|
|
68
|
+
console.log(` Size: ${(new TextEncoder().encode(JSON.stringify(data)).length / 1024).toFixed(2)} KB`);
|
|
69
|
+
// ...
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**The `loadMemory()` function** (line 26-33):
|
|
75
|
+
```javascript
|
|
76
|
+
async function loadMemory() {
|
|
77
|
+
try {
|
|
78
|
+
const content = await fs.readFile(memoryStore, 'utf8'); // hardcoded JSON path
|
|
79
|
+
return JSON.parse(content);
|
|
80
|
+
} catch {
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Where `memoryStore = './memory/memory-store.json'` (line 14)
|
|
87
|
+
|
|
88
|
+
### Why It's Broken
|
|
89
|
+
|
|
90
|
+
1. **Hardcoded JSON File**: `showMemoryStats()` only reads from `./memory/memory-store.json`
|
|
91
|
+
2. **No Mode Detection**: Unlike other commands (`store`, `query`, `list`), `stats` doesn't call `detectMemoryMode()` (line 23)
|
|
92
|
+
3. **No ReasoningBank Support**: The switch statement (lines 56-87) routes `stats` directly to `showMemoryStats()` without checking if ReasoningBank is active
|
|
93
|
+
4. **Inconsistent with Other Commands**: `store`, `query`, and `list` all support `--reasoningbank` flag via `handleReasoningBankCommand()`, but `stats` doesn't
|
|
94
|
+
|
|
95
|
+
### Working Commands for Comparison
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
// ā
These commands properly detect mode and support ReasoningBank
|
|
99
|
+
case 'store':
|
|
100
|
+
await storeMemory(subArgs, loadMemory, saveMemory, namespace, enableRedaction);
|
|
101
|
+
break;
|
|
102
|
+
|
|
103
|
+
case 'query':
|
|
104
|
+
await queryMemory(subArgs, loadMemory, namespace, enableRedaction);
|
|
105
|
+
break;
|
|
106
|
+
|
|
107
|
+
case 'list':
|
|
108
|
+
await listNamespaces(loadMemory);
|
|
109
|
+
break;
|
|
110
|
+
|
|
111
|
+
// ā This command ignores mode detection
|
|
112
|
+
case 'stats':
|
|
113
|
+
await showMemoryStats(loadMemory); // Never checks ReasoningBank!
|
|
114
|
+
break;
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Expected Behavior
|
|
118
|
+
|
|
119
|
+
The `memory stats` command should:
|
|
120
|
+
|
|
121
|
+
1. **Detect the active memory mode** (basic JSON vs ReasoningBank SQLite)
|
|
122
|
+
2. **Show appropriate statistics** based on the active mode:
|
|
123
|
+
- **ReasoningBank mode**: Query SQLite database for accurate counts
|
|
124
|
+
- **Basic mode**: Read JSON file (current behavior)
|
|
125
|
+
- **Auto mode**: Check both and show combined statistics
|
|
126
|
+
3. **Support `--reasoningbank` flag** to force ReasoningBank stats
|
|
127
|
+
4. **Display backend information**: Show which storage backend is being used
|
|
128
|
+
|
|
129
|
+
### Proposed Output
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Auto mode (should detect ReasoningBank if initialized)
|
|
133
|
+
$ npx claude-flow@alpha memory stats
|
|
134
|
+
ā
Memory Bank Statistics:
|
|
135
|
+
Storage Backend: ReasoningBank (SQLite)
|
|
136
|
+
Total Entries: 19
|
|
137
|
+
Namespaces: 3
|
|
138
|
+
Size: 9.14 MB
|
|
139
|
+
|
|
140
|
+
š Namespace Breakdown:
|
|
141
|
+
default: 12 entries
|
|
142
|
+
test-namespace: 5 entries
|
|
143
|
+
api: 2 entries
|
|
144
|
+
|
|
145
|
+
š” Use 'memory stats --basic' for JSON statistics
|
|
146
|
+
|
|
147
|
+
# Force ReasoningBank mode
|
|
148
|
+
$ npx claude-flow@alpha memory stats --reasoningbank
|
|
149
|
+
ā
ReasoningBank Statistics:
|
|
150
|
+
Database: .swarm/memory.db
|
|
151
|
+
Total Memories: 19
|
|
152
|
+
Total Embeddings: 19
|
|
153
|
+
Average Confidence: 80.0%
|
|
154
|
+
Trajectories: 0
|
|
155
|
+
Links: 0
|
|
156
|
+
Database Size: 9.14 MB
|
|
157
|
+
|
|
158
|
+
# Force basic mode
|
|
159
|
+
$ npx claude-flow@alpha memory stats --basic
|
|
160
|
+
ā
JSON Memory Statistics:
|
|
161
|
+
Total Entries: 0
|
|
162
|
+
Namespaces: 0
|
|
163
|
+
Size: 0.00 KB
|
|
164
|
+
ā ļø Consider migrating to ReasoningBank for better performance
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Proposed Solution
|
|
168
|
+
|
|
169
|
+
### Option 1: Add ReasoningBank Support to stats (Recommended)
|
|
170
|
+
|
|
171
|
+
Modify `src/cli/simple-commands/memory.js`:
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
// Line 65-67: Add mode detection to stats case
|
|
175
|
+
case 'stats':
|
|
176
|
+
if (mode === 'reasoningbank') {
|
|
177
|
+
await handleReasoningBankStats(getStatus);
|
|
178
|
+
} else {
|
|
179
|
+
await showMemoryStats(loadMemory);
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
|
|
183
|
+
// Add new handler function (around line 718)
|
|
184
|
+
async function handleReasoningBankStats(getStatus) {
|
|
185
|
+
try {
|
|
186
|
+
const stats = await getStatus();
|
|
187
|
+
|
|
188
|
+
printSuccess('ReasoningBank Statistics:');
|
|
189
|
+
console.log(` Database: ${stats.database_path || '.swarm/memory.db'}`);
|
|
190
|
+
console.log(` Total Memories: ${stats.total_memories}`);
|
|
191
|
+
console.log(` Total Categories: ${stats.total_categories}`);
|
|
192
|
+
console.log(` Average Confidence: ${(stats.avg_confidence * 100).toFixed(1)}%`);
|
|
193
|
+
console.log(` Embeddings: ${stats.total_embeddings}`);
|
|
194
|
+
console.log(` Trajectories: ${stats.total_trajectories}`);
|
|
195
|
+
console.log(` Links: ${stats.total_links || 0}`);
|
|
196
|
+
console.log(` Storage Backend: ${stats.storage_backend}`);
|
|
197
|
+
|
|
198
|
+
if (stats.database_path) {
|
|
199
|
+
const dbSize = await getFileSize(stats.database_path);
|
|
200
|
+
console.log(` Database Size: ${(dbSize / 1024 / 1024).toFixed(2)} MB`);
|
|
201
|
+
}
|
|
202
|
+
} catch (error) {
|
|
203
|
+
printError(`Failed to get ReasoningBank stats: ${error.message}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Helper function
|
|
208
|
+
async function getFileSize(path) {
|
|
209
|
+
try {
|
|
210
|
+
const stats = await fs.stat(path);
|
|
211
|
+
return stats.size;
|
|
212
|
+
} catch {
|
|
213
|
+
return 0;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Option 2: Create Unified Stats Command
|
|
219
|
+
|
|
220
|
+
Show both JSON and ReasoningBank statistics in one output:
|
|
221
|
+
|
|
222
|
+
```javascript
|
|
223
|
+
async function showMemoryStats(loadMemory, mode) {
|
|
224
|
+
const rbInitialized = await isReasoningBankInitialized();
|
|
225
|
+
|
|
226
|
+
printSuccess('Memory Bank Statistics:\n');
|
|
227
|
+
|
|
228
|
+
// Show JSON stats
|
|
229
|
+
const jsonData = await loadMemory();
|
|
230
|
+
let totalEntries = Object.values(jsonData).reduce((sum, arr) => sum + arr.length, 0);
|
|
231
|
+
|
|
232
|
+
console.log('š JSON Storage (./memory/memory-store.json):');
|
|
233
|
+
console.log(` Total Entries: ${totalEntries}`);
|
|
234
|
+
console.log(` Namespaces: ${Object.keys(jsonData).length}`);
|
|
235
|
+
console.log(` Size: ${(new TextEncoder().encode(JSON.stringify(jsonData)).length / 1024).toFixed(2)} KB`);
|
|
236
|
+
|
|
237
|
+
// Show ReasoningBank stats if initialized
|
|
238
|
+
if (rbInitialized) {
|
|
239
|
+
const { getStatus } = await import('../../reasoningbank/reasoningbank-adapter.js');
|
|
240
|
+
const rbStats = await getStatus();
|
|
241
|
+
|
|
242
|
+
console.log('\nš§ ReasoningBank Storage (.swarm/memory.db):');
|
|
243
|
+
console.log(` Total Memories: ${rbStats.total_memories}`);
|
|
244
|
+
console.log(` Categories: ${rbStats.total_categories}`);
|
|
245
|
+
console.log(` Average Confidence: ${(rbStats.avg_confidence * 100).toFixed(1)}%`);
|
|
246
|
+
console.log(` Embeddings: ${rbStats.total_embeddings}`);
|
|
247
|
+
|
|
248
|
+
console.log('\nš” Active Mode: ReasoningBank (auto-selected)');
|
|
249
|
+
} else {
|
|
250
|
+
console.log('\nā ļø ReasoningBank not initialized (using JSON storage)');
|
|
251
|
+
console.log(' Run "memory init --reasoningbank" to enable AI features');
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Testing Plan
|
|
257
|
+
|
|
258
|
+
### Test Cases
|
|
259
|
+
|
|
260
|
+
1. **Test with empty JSON, empty ReasoningBank**
|
|
261
|
+
```bash
|
|
262
|
+
rm -rf memory/ .swarm/
|
|
263
|
+
npx claude-flow@alpha memory stats
|
|
264
|
+
# Expected: Show zeros for both backends
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
2. **Test with data in ReasoningBank only**
|
|
268
|
+
```bash
|
|
269
|
+
npx claude-flow@alpha memory store "test" "value" --reasoningbank
|
|
270
|
+
npx claude-flow@alpha memory stats
|
|
271
|
+
# Expected: Show ReasoningBank stats with 1 entry
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
3. **Test with data in JSON only**
|
|
275
|
+
```bash
|
|
276
|
+
npx claude-flow@alpha memory store "test" "value" --basic
|
|
277
|
+
npx claude-flow@alpha memory stats
|
|
278
|
+
# Expected: Show JSON stats with 1 entry
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
4. **Test with data in both backends**
|
|
282
|
+
```bash
|
|
283
|
+
npx claude-flow@alpha memory store "json-key" "json-value" --basic
|
|
284
|
+
npx claude-flow@alpha memory store "rb-key" "rb-value" --reasoningbank
|
|
285
|
+
npx claude-flow@alpha memory stats
|
|
286
|
+
# Expected: Show stats for both backends
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
5. **Test with flags**
|
|
290
|
+
```bash
|
|
291
|
+
npx claude-flow@alpha memory stats --reasoningbank
|
|
292
|
+
npx claude-flow@alpha memory stats --basic
|
|
293
|
+
npx claude-flow@alpha memory stats --auto
|
|
294
|
+
# Expected: Respect mode flags
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Impact Assessment
|
|
298
|
+
|
|
299
|
+
### User Impact: High
|
|
300
|
+
- Users relying on `memory stats` are seeing incorrect information
|
|
301
|
+
- New users testing ReasoningBank features think it's not working
|
|
302
|
+
- Migration from JSON to ReasoningBank appears unsuccessful
|
|
303
|
+
|
|
304
|
+
### Workarounds
|
|
305
|
+
Users can check ReasoningBank data using:
|
|
306
|
+
1. `memory status --reasoningbank` - Shows basic stats
|
|
307
|
+
2. `memory list --reasoningbank` - Lists all entries
|
|
308
|
+
3. Direct SQLite query: `sqlite3 .swarm/memory.db "SELECT COUNT(*) FROM patterns;"`
|
|
309
|
+
|
|
310
|
+
## Related Issues
|
|
311
|
+
|
|
312
|
+
- Memory mode detection works correctly for `store`, `query`, `list` commands
|
|
313
|
+
- The `status --reasoningbank` command works and shows accurate statistics
|
|
314
|
+
- This bug affects only the `stats` command (without flags)
|
|
315
|
+
|
|
316
|
+
## Files to Modify
|
|
317
|
+
|
|
318
|
+
1. **src/cli/simple-commands/memory.js**
|
|
319
|
+
- Lines 65-67: Add mode detection to `stats` case
|
|
320
|
+
- Lines 217-244: Modify `showMemoryStats()` to support ReasoningBank
|
|
321
|
+
- Add new `handleReasoningBankStats()` function (around line 718)
|
|
322
|
+
|
|
323
|
+
## Backward Compatibility
|
|
324
|
+
|
|
325
|
+
ā
No breaking changes - existing JSON-based stats will continue to work
|
|
326
|
+
ā
New flag `--reasoningbank` is optional
|
|
327
|
+
ā
Auto mode will fall back to JSON if ReasoningBank not initialized
|
|
328
|
+
|
|
329
|
+
## Priority Recommendation
|
|
330
|
+
|
|
331
|
+
**Priority: High** - This is a user-facing bug that makes a primary feature (statistics) non-functional for ReasoningBank users.
|
|
332
|
+
|
|
333
|
+
**Suggested for**: v2.7.31 hotfix
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Additional Context
|
|
338
|
+
|
|
339
|
+
### System Information
|
|
340
|
+
- Version: v2.7.30 (and likely earlier)
|
|
341
|
+
- Database: SQLite 3.x at `.swarm/memory.db`
|
|
342
|
+
- ReasoningBank: Initialized and contains 19 entries
|
|
343
|
+
- JSON Storage: Empty (0 entries)
|
|
344
|
+
|
|
345
|
+
### Reproduction Steps
|
|
346
|
+
1. Initialize ReasoningBank: `npx claude-flow@alpha memory init --reasoningbank`
|
|
347
|
+
2. Store data: `npx claude-flow@alpha memory store test-key "test value" --reasoningbank`
|
|
348
|
+
3. Verify storage: `npx claude-flow@alpha memory list --reasoningbank` (shows data)
|
|
349
|
+
4. Run stats: `npx claude-flow@alpha memory stats` (shows zeros ā)
|
|
350
|
+
|
|
351
|
+
### Related Files
|
|
352
|
+
- `/workspaces/claude-code-flow/src/cli/simple-commands/memory.js` (main bug location)
|
|
353
|
+
- `/workspaces/claude-code-flow/src/reasoningbank/reasoningbank-adapter.js` (working `getStatus()` function)
|
|
354
|
+
- `.swarm/memory.db` (SQLite database with 19 entries)
|
|
355
|
+
- `./memory/memory-store.json` (empty JSON file)
|