From c12ef3e77217a5b7c1c8f6c1c4aa7a03bfcef631 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Sun, 21 Dec 2025 16:39:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20core=5Fmemory=20MC?= =?UTF-8?q?P=20=E5=B7=A5=E5=85=B7=EF=BC=8C=E6=94=AF=E6=8C=81=E8=B7=A8?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=AF=BC=E5=87=BA=E5=92=8C=E7=B2=BE=E7=AE=80?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 findMemoryAcrossProjects 函数,支持按 CMEM-xxx ID 跨所有项目搜索记忆 - export 操作增强:当前项目找不到时自动搜索所有项目数据库 - list 操作优化:返回精简格式,preview 截断为 100 字符,减少输出体积 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- ccw/src/core/core-memory-store.ts | 49 +++++++++++++++++++++++++++++++ ccw/src/tools/core-memory.ts | 48 ++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/ccw/src/core/core-memory-store.ts b/ccw/src/core/core-memory-store.ts index 6d4f6ebc..68c4976e 100644 --- a/ccw/src/core/core-memory-store.ts +++ b/ccw/src/core/core-memory-store.ts @@ -1383,6 +1383,55 @@ export function getMemoriesFromProject(projectId: string): CoreMemory[] { })); } +/** + * Find a memory by ID across all projects + * Searches through all project databases to locate a specific memory + */ +export function findMemoryAcrossProjects(memoryId: string): { memory: CoreMemory; projectId: string } | null { + const projectsDir = join(getCCWHome(), 'projects'); + + if (!existsSync(projectsDir)) { + return null; + } + + const entries = readdirSync(projectsDir, { withFileTypes: true }); + + for (const entry of entries) { + if (!entry.isDirectory()) continue; + + const projectId = entry.name; + const coreMemoryDb = join(projectsDir, projectId, 'core-memory', 'core_memory.db'); + + if (!existsSync(coreMemoryDb)) continue; + + try { + const db = new Database(coreMemoryDb, { readonly: true }); + const row = db.prepare('SELECT * FROM memories WHERE id = ?').get(memoryId) as any; + db.close(); + + if (row) { + return { + memory: { + id: row.id, + content: row.content, + summary: row.summary || '', + raw_output: row.raw_output, + created_at: row.created_at, + updated_at: row.updated_at, + archived: Boolean(row.archived), + metadata: row.metadata + }, + projectId + }; + } + } catch { + // Database might be locked or corrupted, skip + } + } + + return null; +} + /** * Export memories to a JSON file */ diff --git a/ccw/src/tools/core-memory.ts b/ccw/src/tools/core-memory.ts index caa8dfaf..6f5166dc 100644 --- a/ccw/src/tools/core-memory.ts +++ b/ccw/src/tools/core-memory.ts @@ -5,7 +5,7 @@ import { z } from 'zod'; import type { ToolSchema, ToolResult } from '../types/tool.js'; -import { getCoreMemoryStore } from '../core/core-memory-store.js'; +import { getCoreMemoryStore, findMemoryAcrossProjects } from '../core/core-memory-store.js'; import * as MemoryEmbedder from '../core/memory-embedder-bridge.js'; import { StoragePaths } from '../config/storage-paths.js'; import { join } from 'path'; @@ -41,9 +41,17 @@ interface CoreMemory { updated_at: string; } +/** Compact memory info for list operation */ +interface CoreMemoryCompact { + id: string; + preview: string; // Truncated content/summary preview + archived: boolean; + updated_at: string; +} + interface ListResult { operation: 'list'; - memories: CoreMemory[]; + memories: CoreMemoryCompact[]; total: number; } @@ -112,18 +120,36 @@ function getDatabasePath(): string { return join(paths.root, 'core-memory', 'core_memory.db'); } +/** Max preview length for list operation */ +const PREVIEW_MAX_LENGTH = 100; + /** * Operation: list - * List all memories + * List all memories with compact output */ function executeList(params: Params): ListResult { const { limit } = params; const store = getCoreMemoryStore(getProjectPath()); const memories = store.getMemories({ limit }) as CoreMemory[]; + // Convert to compact format with truncated preview + const compactMemories: CoreMemoryCompact[] = memories.map((m) => { + const source = m.summary || m.content; + const preview = source.length > PREVIEW_MAX_LENGTH + ? source.substring(0, PREVIEW_MAX_LENGTH) + '...' + : source; + + return { + id: m.id, + preview, + archived: m.archived, + updated_at: m.updated_at, + }; + }); + return { operation: 'list', - memories, + memories: compactMemories, total: memories.length, }; } @@ -154,6 +180,7 @@ function executeImport(params: Params): ImportResult { /** * Operation: export * Export a memory as plain text + * Searches current project first, then all projects if not found */ function executeExport(params: Params): ExportResult { const { id } = params; @@ -162,11 +189,20 @@ function executeExport(params: Params): ExportResult { throw new Error('Parameter "id" is required for export operation'); } + // Try current project first const store = getCoreMemoryStore(getProjectPath()); - const memory = store.getMemory(id); + let memory = store.getMemory(id); + + // If not found, search across all projects + if (!memory) { + const result = findMemoryAcrossProjects(id); + if (result) { + memory = result.memory; + } + } if (!memory) { - throw new Error(`Memory "${id}" not found`); + throw new Error(`Memory "${id}" not found in any project`); } return {