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.
Files changed (54) hide show
  1. package/dist/chunking/chunker.d.ts +32 -0
  2. package/dist/chunking/chunker.d.ts.map +1 -0
  3. package/dist/chunking/chunker.js +163 -0
  4. package/dist/chunking/chunker.js.map +1 -0
  5. package/dist/claude/sync.d.ts +1 -1
  6. package/dist/claude/sync.d.ts.map +1 -1
  7. package/dist/claude/sync.js +115 -39
  8. package/dist/claude/sync.js.map +1 -1
  9. package/dist/cli/commands/add.d.ts.map +1 -1
  10. package/dist/cli/commands/add.js +46 -12
  11. package/dist/cli/commands/add.js.map +1 -1
  12. package/dist/cli/commands/migrate-chunks.d.ts +15 -0
  13. package/dist/cli/commands/migrate-chunks.d.ts.map +1 -0
  14. package/dist/cli/commands/migrate-chunks.js +205 -0
  15. package/dist/cli/commands/migrate-chunks.js.map +1 -0
  16. package/dist/cli/index.js +2 -0
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/db/database.d.ts +26 -1
  19. package/dist/db/database.d.ts.map +1 -1
  20. package/dist/db/database.js +197 -8
  21. package/dist/db/database.js.map +1 -1
  22. package/dist/hooks/session-start.d.ts.map +1 -1
  23. package/dist/hooks/session-start.js +70 -8
  24. package/dist/hooks/session-start.js.map +1 -1
  25. package/dist/hooks/user-prompt-submit.d.ts.map +1 -1
  26. package/dist/hooks/user-prompt-submit.js +58 -8
  27. package/dist/hooks/user-prompt-submit.js.map +1 -1
  28. package/dist/lifecycle/cleanup.d.ts.map +1 -1
  29. package/dist/lifecycle/cleanup.js +38 -16
  30. package/dist/lifecycle/cleanup.js.map +1 -1
  31. package/dist/lifecycle/tiering.d.ts.map +1 -1
  32. package/dist/lifecycle/tiering.js +1 -0
  33. package/dist/lifecycle/tiering.js.map +1 -1
  34. package/dist/search/index.d.ts +3 -0
  35. package/dist/search/index.d.ts.map +1 -1
  36. package/dist/search/index.js +2 -0
  37. package/dist/search/index.js.map +1 -1
  38. package/dist/search/ranker.d.ts +1 -0
  39. package/dist/search/ranker.d.ts.map +1 -1
  40. package/dist/search/ranker.js +1 -0
  41. package/dist/search/ranker.js.map +1 -1
  42. package/dist/sync/client.d.ts +6 -0
  43. package/dist/sync/client.d.ts.map +1 -1
  44. package/dist/sync/client.js.map +1 -1
  45. package/dist/sync/queue.d.ts.map +1 -1
  46. package/dist/sync/queue.js +10 -0
  47. package/dist/sync/queue.js.map +1 -1
  48. package/dist/sync/synchronizer.d.ts.map +1 -1
  49. package/dist/sync/synchronizer.js +9 -0
  50. package/dist/sync/synchronizer.js.map +1 -1
  51. package/dist/types/index.d.ts +6 -0
  52. package/dist/types/index.d.ts.map +1 -1
  53. package/dist/types/index.js.map +1 -1
  54. 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
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;AAEjE,+CAA+C;AAC/C,IAAI,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC;IAC1C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAAC,MAAM,CAAC;IACP,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,mCAAmC,CAAC;KAChD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;KACpB,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,CAAC;KAC9C,IAAI,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE;IACjC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC;IACrC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACnC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAEzC,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -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":"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"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"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"}
@@ -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('SELECT COUNT(*) as count FROM memories WHERE project_path = ?').get(projectPath).count;
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
  }