a2a-memory 0.10.8 → 0.10.10
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/dist/chunking/chunker.d.ts +32 -0
- package/dist/chunking/chunker.d.ts.map +1 -0
- package/dist/chunking/chunker.js +163 -0
- package/dist/chunking/chunker.js.map +1 -0
- package/dist/claude/sync.d.ts +1 -1
- package/dist/claude/sync.d.ts.map +1 -1
- package/dist/claude/sync.js +115 -39
- package/dist/claude/sync.js.map +1 -1
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/add.js +46 -12
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/migrate-chunks.d.ts +15 -0
- package/dist/cli/commands/migrate-chunks.d.ts.map +1 -0
- package/dist/cli/commands/migrate-chunks.js +205 -0
- package/dist/cli/commands/migrate-chunks.js.map +1 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/db/database.d.ts +26 -1
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/database.js +197 -8
- package/dist/db/database.js.map +1 -1
- package/dist/hooks/session-start.d.ts.map +1 -1
- package/dist/hooks/session-start.js +70 -8
- package/dist/hooks/session-start.js.map +1 -1
- package/dist/hooks/user-prompt-submit.d.ts.map +1 -1
- package/dist/hooks/user-prompt-submit.js +58 -8
- package/dist/hooks/user-prompt-submit.js.map +1 -1
- package/dist/lifecycle/cleanup.d.ts.map +1 -1
- package/dist/lifecycle/cleanup.js +38 -16
- package/dist/lifecycle/cleanup.js.map +1 -1
- package/dist/lifecycle/tiering.d.ts.map +1 -1
- package/dist/lifecycle/tiering.js +1 -0
- package/dist/lifecycle/tiering.js.map +1 -1
- package/dist/search/index.d.ts +3 -0
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +2 -0
- package/dist/search/index.js.map +1 -1
- package/dist/search/ranker.d.ts +1 -0
- package/dist/search/ranker.d.ts.map +1 -1
- package/dist/search/ranker.js +1 -0
- package/dist/search/ranker.js.map +1 -1
- package/dist/sync/client.d.ts +6 -0
- package/dist/sync/client.d.ts.map +1 -1
- package/dist/sync/client.js.map +1 -1
- package/dist/sync/queue.d.ts.map +1 -1
- package/dist/sync/queue.js +10 -0
- package/dist/sync/queue.js.map +1 -1
- package/dist/sync/synchronizer.d.ts.map +1 -1
- package/dist/sync/synchronizer.js +9 -0
- package/dist/sync/synchronizer.js.map +1 -1
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migrate-Chunks Command
|
|
3
|
+
*
|
|
4
|
+
* 레거시 claude-md-sync 메모리(독립 섹션)를 Parent-Child 구조로 마이그레이션합니다.
|
|
5
|
+
*
|
|
6
|
+
* 동작:
|
|
7
|
+
* 1. claude-md-sync 태그 + section:* 태그 + parent_id=NULL인 레거시 메모리 탐색
|
|
8
|
+
* 2. source 파일별로 그룹핑
|
|
9
|
+
* 3. 원본 파일 읽기 → Parent 생성
|
|
10
|
+
* 4. 섹션 재파싱 → Children 생성
|
|
11
|
+
* 5. 레거시 메모리 삭제 (tombstone + sync 상태 보존)
|
|
12
|
+
*/
|
|
13
|
+
import { Command } from 'commander';
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
16
|
+
import { createHash } from 'node:crypto';
|
|
17
|
+
import { ConfigManager } from '../../config/manager.js';
|
|
18
|
+
import { MemoryDatabase } from '../../db/database.js';
|
|
19
|
+
import { parseClaudeMd, findClaudeMd } from '../../claude/sync.js';
|
|
20
|
+
const CLAUDE_MD_TAG = 'claude-md-sync';
|
|
21
|
+
/**
|
|
22
|
+
* 레거시 claude-md-sync 메모리를 탐색하여 파일별로 그룹핑
|
|
23
|
+
*/
|
|
24
|
+
function findLegacyGroups(db, projectPath) {
|
|
25
|
+
// claude-md-sync 태그를 가진 모든 메모리 조회
|
|
26
|
+
const allSyncMemories = db.findMemoriesByTag(CLAUDE_MD_TAG);
|
|
27
|
+
// 레거시 조건: parent_id=NULL + section:* 태그 보유 + source:* 태그 없음 (또는 있어도 chunk_total 없음)
|
|
28
|
+
const legacyMemories = allSyncMemories.filter(m => !m.parentId &&
|
|
29
|
+
!m.chunkTotal &&
|
|
30
|
+
m.tags.some(t => t.startsWith('section:')));
|
|
31
|
+
if (legacyMemories.length === 0)
|
|
32
|
+
return [];
|
|
33
|
+
// source:* 태그 기반 그룹핑
|
|
34
|
+
const groups = new Map();
|
|
35
|
+
for (const m of legacyMemories) {
|
|
36
|
+
const sourceTag = m.tags.find(t => t.startsWith('source:'));
|
|
37
|
+
const filename = sourceTag ? sourceTag.slice(7) : 'CLAUDE.md';
|
|
38
|
+
const list = groups.get(filename) ?? [];
|
|
39
|
+
list.push(m);
|
|
40
|
+
groups.set(filename, list);
|
|
41
|
+
}
|
|
42
|
+
// 파일 경로 추정
|
|
43
|
+
const result = [];
|
|
44
|
+
for (const [filename, memories] of groups) {
|
|
45
|
+
let filePath = null;
|
|
46
|
+
// projectPath 기반 탐색
|
|
47
|
+
if (projectPath) {
|
|
48
|
+
const candidates = [
|
|
49
|
+
`${projectPath}/${filename}`,
|
|
50
|
+
`${projectPath}/.claude/${filename}`,
|
|
51
|
+
];
|
|
52
|
+
filePath = candidates.find(p => existsSync(p)) ?? null;
|
|
53
|
+
}
|
|
54
|
+
// 기본 CLAUDE.md 탐색
|
|
55
|
+
if (!filePath && filename === 'CLAUDE.md') {
|
|
56
|
+
filePath = findClaudeMd(projectPath);
|
|
57
|
+
}
|
|
58
|
+
result.push({ filename, memories, filePath });
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 단일 그룹 마이그레이션 실행
|
|
64
|
+
*/
|
|
65
|
+
function migrateGroup(db, group, options) {
|
|
66
|
+
if (!group.filePath) {
|
|
67
|
+
return { created: 0, deleted: 0, parentId: null };
|
|
68
|
+
}
|
|
69
|
+
const content = readFileSync(group.filePath, 'utf-8');
|
|
70
|
+
const sections = parseClaudeMd(content);
|
|
71
|
+
if (sections.length === 0) {
|
|
72
|
+
return { created: 0, deleted: 0, parentId: null };
|
|
73
|
+
}
|
|
74
|
+
if (options.dryRun) {
|
|
75
|
+
return {
|
|
76
|
+
created: sections.length + 1, // Parent + Children
|
|
77
|
+
deleted: group.memories.length,
|
|
78
|
+
parentId: null,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// sync 상태 보존 (레거시 메모리의 remoteId 수집)
|
|
82
|
+
const syncMap = new Map();
|
|
83
|
+
for (const m of group.memories) {
|
|
84
|
+
const status = db.getSyncStatus(m.id);
|
|
85
|
+
if (status?.remoteId) {
|
|
86
|
+
const sectionTag = m.tags.find(t => t.startsWith('section:'));
|
|
87
|
+
if (sectionTag) {
|
|
88
|
+
syncMap.set(sectionTag, status.remoteId);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// 레거시 메모리 삭제 (tombstone 포함)
|
|
93
|
+
for (const m of group.memories) {
|
|
94
|
+
db.deleteMemory(m.id);
|
|
95
|
+
}
|
|
96
|
+
// Parent-Child 생성
|
|
97
|
+
const contentHash = createHash('sha256').update(content).digest('hex').slice(0, 16);
|
|
98
|
+
const projectPath = options.projectPath ?? process.cwd();
|
|
99
|
+
const parentTags = [CLAUDE_MD_TAG, `source:${group.filename}`, `hash:${contentHash}`];
|
|
100
|
+
const childInputs = sections.map((section) => {
|
|
101
|
+
const sectionHash = createHash('sha256').update(section.content).digest('hex').slice(0, 16);
|
|
102
|
+
return {
|
|
103
|
+
content: `[CLAUDE.md: ${section.title}]\nSource: ${group.filename}\n\n${section.content}`,
|
|
104
|
+
category: classifySection(section.title),
|
|
105
|
+
tier: 'semantic',
|
|
106
|
+
tags: [CLAUDE_MD_TAG, `section:${section.title}`, `hash:${sectionHash}`, `source:${group.filename}`],
|
|
107
|
+
projectPath,
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
const parentId = db.createMemoryWithChunks({
|
|
111
|
+
content,
|
|
112
|
+
category: 'project_knowledge',
|
|
113
|
+
tier: 'semantic',
|
|
114
|
+
tags: parentTags,
|
|
115
|
+
projectPath,
|
|
116
|
+
}, childInputs);
|
|
117
|
+
// sync 상태 복원: Children에 이전 remoteId 매핑
|
|
118
|
+
if (syncMap.size > 0) {
|
|
119
|
+
const children = db.getChildChunks(parentId);
|
|
120
|
+
for (const child of children) {
|
|
121
|
+
const sectionTag = child.tags.find(t => t.startsWith('section:'));
|
|
122
|
+
if (sectionTag && syncMap.has(sectionTag)) {
|
|
123
|
+
db.setSyncStatus(child.id, syncMap.get(sectionTag), 'pending');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
created: sections.length + 1,
|
|
129
|
+
deleted: group.memories.length,
|
|
130
|
+
parentId,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 섹션 제목으로 카테고리 분류 (sync.ts와 동일 로직)
|
|
135
|
+
*/
|
|
136
|
+
function classifySection(title) {
|
|
137
|
+
const lower = title.toLowerCase();
|
|
138
|
+
if (lower.includes('convention') || lower.includes('규칙') || lower.includes('rule') ||
|
|
139
|
+
lower.includes('스타일') || lower.includes('style') || lower.includes('패턴') ||
|
|
140
|
+
lower.includes('pattern') || lower.includes('원칙'))
|
|
141
|
+
return 'convention';
|
|
142
|
+
if (lower.includes('결정') || lower.includes('decision') || lower.includes('선택') ||
|
|
143
|
+
lower.includes('why') || lower.includes('이유'))
|
|
144
|
+
return 'decision';
|
|
145
|
+
if (lower.includes('에러') || lower.includes('error') || lower.includes('문제') ||
|
|
146
|
+
lower.includes('trouble') || lower.includes('fix') || lower.includes('해결'))
|
|
147
|
+
return 'error_solution';
|
|
148
|
+
if (lower.includes('학습') || lower.includes('learning') || lower.includes('배운'))
|
|
149
|
+
return 'learning';
|
|
150
|
+
return 'project_knowledge';
|
|
151
|
+
}
|
|
152
|
+
export function migrateChunksCommand() {
|
|
153
|
+
return new Command('migrate-chunks')
|
|
154
|
+
.description('Migrate legacy claude-md-sync memories to Parent-Child pattern')
|
|
155
|
+
.option('--dry-run', 'Show what would be migrated without writing')
|
|
156
|
+
.option('-p, --project <path>', 'Project path (for CLAUDE.md lookup)')
|
|
157
|
+
.action(async (options) => {
|
|
158
|
+
const config = new ConfigManager().load();
|
|
159
|
+
const db = new MemoryDatabase(config.db.path);
|
|
160
|
+
try {
|
|
161
|
+
db.initialize();
|
|
162
|
+
const groups = findLegacyGroups(db, options.project);
|
|
163
|
+
if (groups.length === 0) {
|
|
164
|
+
console.log(chalk.green('\n✓ No legacy memories to migrate. Already using Parent-Child pattern.\n'));
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const prefix = options.dryRun ? chalk.cyan('[DRY RUN] ') : '';
|
|
168
|
+
console.log(chalk.bold(`\n${prefix}📦 Migrate-Chunks: Legacy → Parent-Child\n`));
|
|
169
|
+
let totalCreated = 0;
|
|
170
|
+
let totalDeleted = 0;
|
|
171
|
+
for (const group of groups) {
|
|
172
|
+
console.log(chalk.dim(`─── ${group.filename} (${group.memories.length} legacy memories) ───`));
|
|
173
|
+
if (!group.filePath) {
|
|
174
|
+
console.log(chalk.yellow(` ⚠️ Source file not found. Skipping.`));
|
|
175
|
+
console.log(chalk.dim(` Use --project <path> to specify project root.\n`));
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
console.log(chalk.dim(` Source: ${group.filePath}`));
|
|
179
|
+
const result = migrateGroup(db, group, {
|
|
180
|
+
dryRun: options.dryRun ?? false,
|
|
181
|
+
projectPath: options.project,
|
|
182
|
+
});
|
|
183
|
+
if (result.parentId) {
|
|
184
|
+
console.log(chalk.green(` ✓ Parent: ${result.parentId}`));
|
|
185
|
+
}
|
|
186
|
+
console.log(chalk.dim(` Created: ${result.created} | Deleted: ${result.deleted}\n`));
|
|
187
|
+
totalCreated += result.created;
|
|
188
|
+
totalDeleted += result.deleted;
|
|
189
|
+
}
|
|
190
|
+
console.log(chalk.bold('Summary:'));
|
|
191
|
+
console.log(` ${chalk.green(`Created: ${totalCreated}`)} | ${chalk.red(`Deleted: ${totalDeleted}`)}`);
|
|
192
|
+
console.log();
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
if (error instanceof Error) {
|
|
196
|
+
console.error(chalk.red(`\n❌ Migration error: ${error.message}\n`));
|
|
197
|
+
}
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
finally {
|
|
201
|
+
db.close();
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=migrate-chunks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate-chunks.js","sourceRoot":"","sources":["../../../src/cli/commands/migrate-chunks.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -34,6 +34,7 @@ import { healthCommand } from './commands/health.js';
|
|
|
34
34
|
import { claudeSyncCommand } from './commands/claude-sync.js';
|
|
35
35
|
import { skillCommand } from './commands/skill.js';
|
|
36
36
|
import { proficiencyCommand } from './commands/proficiency.js';
|
|
37
|
+
import { migrateChunksCommand } from './commands/migrate-chunks.js';
|
|
37
38
|
import { setLocale, detectLocale } from '../i18n/index.js';
|
|
38
39
|
import { ConfigManager } from '../config/manager.js';
|
|
39
40
|
const require = createRequire(import.meta.url);
|
|
@@ -80,5 +81,6 @@ program.addCommand(healthCommand());
|
|
|
80
81
|
program.addCommand(claudeSyncCommand());
|
|
81
82
|
program.addCommand(skillCommand());
|
|
82
83
|
program.addCommand(proficiencyCommand());
|
|
84
|
+
program.addCommand(migrateChunksCommand());
|
|
83
85
|
program.parse();
|
|
84
86
|
//# sourceMappingURL=index.js.map
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
package/dist/db/database.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export declare class MemoryDatabase {
|
|
|
29
29
|
category?: MemoryCategory;
|
|
30
30
|
tier?: MemoryTier;
|
|
31
31
|
projectPath?: string;
|
|
32
|
+
excludeParents?: boolean;
|
|
32
33
|
}): Memory[];
|
|
33
34
|
searchByFTS(query: string, limit?: number): MemorySearchResult[];
|
|
34
35
|
searchByVector(embedding: number[], limit?: number, minScore?: number, projectPath?: string): MemorySearchResult[];
|
|
@@ -95,7 +96,7 @@ export declare class MemoryDatabase {
|
|
|
95
96
|
getMemoriesOlderThan(days: number): Memory[];
|
|
96
97
|
getMemoriesWithoutEmbedding(limit?: number): Memory[];
|
|
97
98
|
deleteMemories(ids: string[]): number;
|
|
98
|
-
getMemoryCount(projectPath?: string): number;
|
|
99
|
+
getMemoryCount(projectPath?: string, excludeChildren?: boolean): number;
|
|
99
100
|
/**
|
|
100
101
|
* 레거시 category/tier 값을 새 스키마로 마이그레이션
|
|
101
102
|
* preference → convention, procedural → semantic
|
|
@@ -104,6 +105,30 @@ export declare class MemoryDatabase {
|
|
|
104
105
|
categoriesUpdated: number;
|
|
105
106
|
tiersUpdated: number;
|
|
106
107
|
};
|
|
108
|
+
/**
|
|
109
|
+
* Parent + Children 일괄 생성 (트랜잭션)
|
|
110
|
+
*/
|
|
111
|
+
createMemoryWithChunks(parent: MemoryCreateInput, children: MemoryCreateInput[]): string;
|
|
112
|
+
/**
|
|
113
|
+
* Parent의 모든 Child chunks 조회 (chunk_index 순)
|
|
114
|
+
*/
|
|
115
|
+
getChildChunks(parentId: string): Memory[];
|
|
116
|
+
/**
|
|
117
|
+
* Child의 Parent 조회
|
|
118
|
+
*/
|
|
119
|
+
getParentMemory(childId: string): Memory | null;
|
|
120
|
+
/**
|
|
121
|
+
* Parent-Child를 원자적으로 교체 (delete old + create new in single transaction)
|
|
122
|
+
*/
|
|
123
|
+
replaceMemoryWithChunks(oldParentId: string, newParent: MemoryCreateInput, newChildren: MemoryCreateInput[]): string;
|
|
124
|
+
/**
|
|
125
|
+
* Parent와 모든 Children 일괄 삭제
|
|
126
|
+
*/
|
|
127
|
+
deleteWithChildren(parentId: string): number;
|
|
128
|
+
/**
|
|
129
|
+
* 특정 태그를 가진 메모리 전체 조회 (tag 인덱스 JOIN 기반)
|
|
130
|
+
*/
|
|
131
|
+
findMemoriesByTag(tag: string): Memory[];
|
|
107
132
|
private getRowId;
|
|
108
133
|
private rowToMemory;
|
|
109
134
|
private rowsToMemories;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EACV,MAAM,EACN,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAmBlF,qBAAa,cAAc;IACzB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,iBAAiB,CAAoB;gBAEjC,MAAM,GAAE,MAAwB,EAAE,iBAAiB,GAAE,iBAA0B;IAgB3F,OAAO,CAAC,IAAI;IASZ,UAAU,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"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"}
|
package/dist/db/database.js
CHANGED
|
@@ -190,6 +190,20 @@ export class MemoryDatabase {
|
|
|
190
190
|
);
|
|
191
191
|
CREATE INDEX IF NOT EXISTS idx_emotion_buffer_synced ON emotion_buffer(synced);
|
|
192
192
|
`);
|
|
193
|
+
// Parent-Child chunk 컬럼 추가 (기존 DB 호환)
|
|
194
|
+
try {
|
|
195
|
+
this.db.exec('ALTER TABLE memories ADD COLUMN parent_id TEXT');
|
|
196
|
+
}
|
|
197
|
+
catch { /* 이미 존재하면 무시 */ }
|
|
198
|
+
try {
|
|
199
|
+
this.db.exec('ALTER TABLE memories ADD COLUMN chunk_index INTEGER');
|
|
200
|
+
}
|
|
201
|
+
catch { /* 이미 존재하면 무시 */ }
|
|
202
|
+
try {
|
|
203
|
+
this.db.exec('ALTER TABLE memories ADD COLUMN chunk_total INTEGER');
|
|
204
|
+
}
|
|
205
|
+
catch { /* 이미 존재하면 무시 */ }
|
|
206
|
+
this.db.exec('CREATE INDEX IF NOT EXISTS idx_memories_parent_id ON memories(parent_id)');
|
|
193
207
|
}
|
|
194
208
|
// ============================
|
|
195
209
|
// CRUD
|
|
@@ -199,13 +213,13 @@ export class MemoryDatabase {
|
|
|
199
213
|
const now = new Date().toISOString();
|
|
200
214
|
const tags = input.tags ?? [];
|
|
201
215
|
const insertMemory = this.stmt('insert_memory', `
|
|
202
|
-
INSERT INTO memories (id, content, category, tier, project_path, session_id, created_at, updated_at)
|
|
203
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
216
|
+
INSERT INTO memories (id, content, category, tier, project_path, session_id, created_at, updated_at, parent_id, chunk_index, chunk_total)
|
|
217
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
204
218
|
`);
|
|
205
219
|
const insertTag = this.stmt('insert_tag', 'INSERT INTO memory_tags (memory_id, tag) VALUES (?, ?)');
|
|
206
220
|
const insertFts = this.stmt('insert_fts', 'INSERT INTO memory_fts (rowid, content) VALUES (?, ?)');
|
|
207
221
|
const runTransaction = this.db.transaction(() => {
|
|
208
|
-
insertMemory.run(id, input.content, input.category, input.tier, input.projectPath ?? null, input.sessionId ?? null, now, now);
|
|
222
|
+
insertMemory.run(id, input.content, input.category, input.tier, input.projectPath ?? null, input.sessionId ?? null, now, now, input.parentId ?? null, input.chunkIndex ?? null, input.chunkTotal ?? null);
|
|
209
223
|
for (const tag of tags) {
|
|
210
224
|
insertTag.run(id, tag);
|
|
211
225
|
}
|
|
@@ -224,6 +238,9 @@ export class MemoryDatabase {
|
|
|
224
238
|
createdAt: now,
|
|
225
239
|
updatedAt: now,
|
|
226
240
|
accessCount: 0,
|
|
241
|
+
parentId: input.parentId,
|
|
242
|
+
chunkIndex: input.chunkIndex,
|
|
243
|
+
chunkTotal: input.chunkTotal,
|
|
227
244
|
};
|
|
228
245
|
}
|
|
229
246
|
getMemory(id) {
|
|
@@ -310,6 +327,11 @@ export class MemoryDatabase {
|
|
|
310
327
|
conditions.push('project_path = ?');
|
|
311
328
|
values.push(options.projectPath);
|
|
312
329
|
}
|
|
330
|
+
// excludeParents: Parent 메모리(parent_id IS NULL AND chunk_total IS NOT NULL) 제외
|
|
331
|
+
// Child(parent_id IS NOT NULL) + 독립 메모리(parent_id IS NULL AND chunk_total IS NULL)만 반환
|
|
332
|
+
if (options?.excludeParents) {
|
|
333
|
+
conditions.push('(parent_id IS NOT NULL OR (parent_id IS NULL AND chunk_total IS NULL))');
|
|
334
|
+
}
|
|
313
335
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
314
336
|
const limit = options?.limit ?? 50;
|
|
315
337
|
const offset = options?.offset ?? 0;
|
|
@@ -325,6 +347,7 @@ export class MemoryDatabase {
|
|
|
325
347
|
FROM memory_fts fts
|
|
326
348
|
JOIN memories m ON m.rowid = fts.rowid
|
|
327
349
|
WHERE memory_fts MATCH ?
|
|
350
|
+
AND (m.parent_id IS NOT NULL OR (m.parent_id IS NULL AND m.chunk_total IS NULL))
|
|
328
351
|
ORDER BY fts.rank
|
|
329
352
|
LIMIT ?
|
|
330
353
|
`).all(query, limit);
|
|
@@ -337,9 +360,10 @@ export class MemoryDatabase {
|
|
|
337
360
|
}
|
|
338
361
|
searchByVector(embedding, limit = 10, minScore = 0.5, projectPath) {
|
|
339
362
|
// C-4: 후보 풀 (1000) + 코사인 유사도 계산
|
|
363
|
+
// Parent 메모리(parent_id IS NULL AND chunk_total IS NOT NULL) 제외 — Child + 독립 메모리만 반환
|
|
340
364
|
const rows = projectPath
|
|
341
|
-
? this.stmt('vector_search_project', 'SELECT * FROM memories WHERE embedding IS NOT NULL AND project_path = ? LIMIT 1000').all(projectPath)
|
|
342
|
-
: this.stmt('vector_search_all', 'SELECT * FROM memories WHERE embedding IS NOT NULL LIMIT 1000').all();
|
|
365
|
+
? this.stmt('vector_search_project', 'SELECT * FROM memories WHERE embedding IS NOT NULL AND project_path = ? AND (parent_id IS NOT NULL OR (parent_id IS NULL AND chunk_total IS NULL)) LIMIT 1000').all(projectPath)
|
|
366
|
+
: this.stmt('vector_search_all', 'SELECT * FROM memories WHERE embedding IS NOT NULL AND (parent_id IS NOT NULL OR (parent_id IS NULL AND chunk_total IS NULL)) LIMIT 1000').all();
|
|
343
367
|
const scored = rows
|
|
344
368
|
.map((row) => {
|
|
345
369
|
const stored = bufferToFloat32Array(row.embedding);
|
|
@@ -476,7 +500,8 @@ export class MemoryDatabase {
|
|
|
476
500
|
const rows = this.db.prepare(`
|
|
477
501
|
SELECT m.id, m.content, m.category, m.tier, NULL as embedding,
|
|
478
502
|
m.project_path, m.session_id, m.created_at, m.updated_at,
|
|
479
|
-
m.access_count, m.last_accessed_at
|
|
503
|
+
m.access_count, m.last_accessed_at, NULL as embedding_hash,
|
|
504
|
+
m.parent_id, m.chunk_index, m.chunk_total
|
|
480
505
|
FROM memories m
|
|
481
506
|
LEFT JOIN sync_status s ON m.id = s.memory_id
|
|
482
507
|
WHERE s.sync_state = 'pending' OR s.sync_state IS NULL
|
|
@@ -660,9 +685,13 @@ export class MemoryDatabase {
|
|
|
660
685
|
});
|
|
661
686
|
return transaction();
|
|
662
687
|
}
|
|
663
|
-
getMemoryCount(projectPath) {
|
|
688
|
+
getMemoryCount(projectPath, excludeChildren) {
|
|
689
|
+
const childFilter = excludeChildren ? ' AND parent_id IS NULL' : '';
|
|
664
690
|
if (projectPath) {
|
|
665
|
-
return this.db.prepare(
|
|
691
|
+
return this.db.prepare(`SELECT COUNT(*) as count FROM memories WHERE project_path = ?${childFilter}`).get(projectPath).count;
|
|
692
|
+
}
|
|
693
|
+
if (excludeChildren) {
|
|
694
|
+
return this.db.prepare('SELECT COUNT(*) as count FROM memories WHERE parent_id IS NULL').get().count;
|
|
666
695
|
}
|
|
667
696
|
return this.stmt('count_memories', 'SELECT COUNT(*) as count FROM memories').get().count;
|
|
668
697
|
}
|
|
@@ -682,6 +711,160 @@ export class MemoryDatabase {
|
|
|
682
711
|
};
|
|
683
712
|
}
|
|
684
713
|
// ============================
|
|
714
|
+
// Parent-Child Chunks
|
|
715
|
+
// ============================
|
|
716
|
+
/**
|
|
717
|
+
* Parent + Children 일괄 생성 (트랜잭션)
|
|
718
|
+
*/
|
|
719
|
+
createMemoryWithChunks(parent, children) {
|
|
720
|
+
if (children.length === 0) {
|
|
721
|
+
return this.createMemory(parent).id;
|
|
722
|
+
}
|
|
723
|
+
const parentId = randomUUID();
|
|
724
|
+
const now = new Date().toISOString();
|
|
725
|
+
const chunkTotal = children.length;
|
|
726
|
+
const insertMemory = this.stmt('insert_memory', `
|
|
727
|
+
INSERT INTO memories (id, content, category, tier, project_path, session_id, created_at, updated_at, parent_id, chunk_index, chunk_total)
|
|
728
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
729
|
+
`);
|
|
730
|
+
const insertTag = this.stmt('insert_tag', 'INSERT INTO memory_tags (memory_id, tag) VALUES (?, ?)');
|
|
731
|
+
const insertFts = this.stmt('insert_fts', 'INSERT INTO memory_fts (rowid, content) VALUES (?, ?)');
|
|
732
|
+
const runTransaction = this.db.transaction(() => {
|
|
733
|
+
// Parent 생성 (parent_id=NULL, chunk_total 설정)
|
|
734
|
+
const parentTags = parent.tags ?? [];
|
|
735
|
+
insertMemory.run(parentId, parent.content, parent.category, parent.tier, parent.projectPath ?? null, parent.sessionId ?? null, now, now, null, null, chunkTotal);
|
|
736
|
+
for (const tag of parentTags) {
|
|
737
|
+
insertTag.run(parentId, tag);
|
|
738
|
+
}
|
|
739
|
+
const parentRowId = this.getRowId(parentId);
|
|
740
|
+
insertFts.run(parentRowId, parent.content);
|
|
741
|
+
// Children 생성
|
|
742
|
+
for (let i = 0; i < children.length; i++) {
|
|
743
|
+
const childId = randomUUID();
|
|
744
|
+
const child = children[i];
|
|
745
|
+
const childTags = child.tags ?? [];
|
|
746
|
+
insertMemory.run(childId, child.content, child.category, child.tier, child.projectPath ?? null, child.sessionId ?? null, now, now, parentId, i, chunkTotal);
|
|
747
|
+
for (const tag of childTags) {
|
|
748
|
+
insertTag.run(childId, tag);
|
|
749
|
+
}
|
|
750
|
+
const childRowId = this.getRowId(childId);
|
|
751
|
+
insertFts.run(childRowId, child.content);
|
|
752
|
+
}
|
|
753
|
+
});
|
|
754
|
+
runTransaction();
|
|
755
|
+
return parentId;
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* Parent의 모든 Child chunks 조회 (chunk_index 순)
|
|
759
|
+
*/
|
|
760
|
+
getChildChunks(parentId) {
|
|
761
|
+
const rows = this.db.prepare('SELECT * FROM memories WHERE parent_id = ? ORDER BY chunk_index ASC').all(parentId);
|
|
762
|
+
return this.rowsToMemories(rows);
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* Child의 Parent 조회
|
|
766
|
+
*/
|
|
767
|
+
getParentMemory(childId) {
|
|
768
|
+
const child = this.stmt('get_memory', 'SELECT * FROM memories WHERE id = ?').get(childId);
|
|
769
|
+
if (!child?.parent_id)
|
|
770
|
+
return null;
|
|
771
|
+
return this.getMemory(child.parent_id);
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Parent-Child를 원자적으로 교체 (delete old + create new in single transaction)
|
|
775
|
+
*/
|
|
776
|
+
replaceMemoryWithChunks(oldParentId, newParent, newChildren) {
|
|
777
|
+
const transaction = this.db.transaction(() => {
|
|
778
|
+
// 1. 기존 Parent+Children 삭제
|
|
779
|
+
const oldChildren = this.db.prepare('SELECT id FROM memories WHERE parent_id = ?').all(oldParentId);
|
|
780
|
+
for (const child of oldChildren) {
|
|
781
|
+
this.addTombstone(child.id);
|
|
782
|
+
const rowId = this.getRowId(child.id);
|
|
783
|
+
if (rowId !== null) {
|
|
784
|
+
this.stmt('delete_fts', 'DELETE FROM memory_fts WHERE rowid = ?').run(rowId);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
this.addTombstone(oldParentId);
|
|
788
|
+
const oldParentRowId = this.getRowId(oldParentId);
|
|
789
|
+
if (oldParentRowId !== null) {
|
|
790
|
+
this.stmt('delete_fts', 'DELETE FROM memory_fts WHERE rowid = ?').run(oldParentRowId);
|
|
791
|
+
}
|
|
792
|
+
this.db.prepare('DELETE FROM memories WHERE parent_id = ?').run(oldParentId);
|
|
793
|
+
this.stmt('delete_memory', 'DELETE FROM memories WHERE id = ?').run(oldParentId);
|
|
794
|
+
// 2. 새 Parent+Children 생성
|
|
795
|
+
const parentId = randomUUID();
|
|
796
|
+
const now = new Date().toISOString();
|
|
797
|
+
const chunkTotal = newChildren.length === 0 ? undefined : newChildren.length;
|
|
798
|
+
const insertMemory = this.stmt('insert_memory', `
|
|
799
|
+
INSERT INTO memories (id, content, category, tier, project_path, session_id, created_at, updated_at, parent_id, chunk_index, chunk_total)
|
|
800
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
801
|
+
`);
|
|
802
|
+
const insertTag = this.stmt('insert_tag', 'INSERT INTO memory_tags (memory_id, tag) VALUES (?, ?)');
|
|
803
|
+
const insertFts = this.stmt('insert_fts', 'INSERT INTO memory_fts (rowid, content) VALUES (?, ?)');
|
|
804
|
+
// Parent
|
|
805
|
+
const parentTags = newParent.tags ?? [];
|
|
806
|
+
insertMemory.run(parentId, newParent.content, newParent.category, newParent.tier, newParent.projectPath ?? null, newParent.sessionId ?? null, now, now, null, null, chunkTotal ?? null);
|
|
807
|
+
for (const tag of parentTags) {
|
|
808
|
+
insertTag.run(parentId, tag);
|
|
809
|
+
}
|
|
810
|
+
const parentRowId = this.getRowId(parentId);
|
|
811
|
+
insertFts.run(parentRowId, newParent.content);
|
|
812
|
+
// Children
|
|
813
|
+
for (let i = 0; i < newChildren.length; i++) {
|
|
814
|
+
const childId = randomUUID();
|
|
815
|
+
const child = newChildren[i];
|
|
816
|
+
const childTags = child.tags ?? [];
|
|
817
|
+
insertMemory.run(childId, child.content, child.category, child.tier, child.projectPath ?? null, child.sessionId ?? null, now, now, parentId, i, chunkTotal ?? null);
|
|
818
|
+
for (const tag of childTags) {
|
|
819
|
+
insertTag.run(childId, tag);
|
|
820
|
+
}
|
|
821
|
+
const childRowId = this.getRowId(childId);
|
|
822
|
+
insertFts.run(childRowId, child.content);
|
|
823
|
+
}
|
|
824
|
+
return parentId;
|
|
825
|
+
});
|
|
826
|
+
return transaction();
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Parent와 모든 Children 일괄 삭제
|
|
830
|
+
*/
|
|
831
|
+
deleteWithChildren(parentId) {
|
|
832
|
+
const transaction = this.db.transaction(() => {
|
|
833
|
+
// Children의 FTS, tombstone 처리
|
|
834
|
+
const children = this.db.prepare('SELECT id FROM memories WHERE parent_id = ?').all(parentId);
|
|
835
|
+
for (const child of children) {
|
|
836
|
+
this.addTombstone(child.id);
|
|
837
|
+
const rowId = this.getRowId(child.id);
|
|
838
|
+
if (rowId !== null) {
|
|
839
|
+
this.stmt('delete_fts', 'DELETE FROM memory_fts WHERE rowid = ?').run(rowId);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
// Parent 자체도 처리
|
|
843
|
+
this.addTombstone(parentId);
|
|
844
|
+
const parentRowId = this.getRowId(parentId);
|
|
845
|
+
if (parentRowId !== null) {
|
|
846
|
+
this.stmt('delete_fts', 'DELETE FROM memory_fts WHERE rowid = ?').run(parentRowId);
|
|
847
|
+
}
|
|
848
|
+
// Children 수동 삭제 (FK CASCADE DDL 없음)
|
|
849
|
+
const childResult = this.db.prepare('DELETE FROM memories WHERE parent_id = ?').run(parentId);
|
|
850
|
+
const parentResult = this.stmt('delete_memory', 'DELETE FROM memories WHERE id = ?').run(parentId);
|
|
851
|
+
return childResult.changes + parentResult.changes;
|
|
852
|
+
});
|
|
853
|
+
return transaction();
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* 특정 태그를 가진 메모리 전체 조회 (tag 인덱스 JOIN 기반)
|
|
857
|
+
*/
|
|
858
|
+
findMemoriesByTag(tag) {
|
|
859
|
+
const rows = this.db.prepare(`
|
|
860
|
+
SELECT m.* FROM memories m
|
|
861
|
+
JOIN memory_tags t ON m.id = t.memory_id
|
|
862
|
+
WHERE t.tag = ?
|
|
863
|
+
ORDER BY m.updated_at DESC
|
|
864
|
+
`).all(tag);
|
|
865
|
+
return this.rowsToMemories(rows);
|
|
866
|
+
}
|
|
867
|
+
// ============================
|
|
685
868
|
// Private helpers
|
|
686
869
|
// ============================
|
|
687
870
|
getRowId(id) {
|
|
@@ -725,6 +908,9 @@ export class MemoryDatabase {
|
|
|
725
908
|
updatedAt: row.updated_at,
|
|
726
909
|
accessCount: row.access_count,
|
|
727
910
|
lastAccessedAt: row.last_accessed_at ?? undefined,
|
|
911
|
+
parentId: row.parent_id ?? undefined,
|
|
912
|
+
chunkIndex: row.chunk_index ?? undefined,
|
|
913
|
+
chunkTotal: row.chunk_total ?? undefined,
|
|
728
914
|
};
|
|
729
915
|
}
|
|
730
916
|
rowsToMemories(rows) {
|
|
@@ -790,6 +976,9 @@ export class MemoryDatabase {
|
|
|
790
976
|
updatedAt: row.updated_at,
|
|
791
977
|
accessCount: row.access_count,
|
|
792
978
|
lastAccessedAt: row.last_accessed_at ?? undefined,
|
|
979
|
+
parentId: row.parent_id ?? undefined,
|
|
980
|
+
chunkIndex: row.chunk_index ?? undefined,
|
|
981
|
+
chunkTotal: row.chunk_total ?? undefined,
|
|
793
982
|
};
|
|
794
983
|
});
|
|
795
984
|
}
|