claude-memory-layer 1.0.0
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/.claude-plugin/commands/memory-forget.md +42 -0
- package/.claude-plugin/commands/memory-history.md +34 -0
- package/.claude-plugin/commands/memory-import.md +56 -0
- package/.claude-plugin/commands/memory-list.md +37 -0
- package/.claude-plugin/commands/memory-search.md +36 -0
- package/.claude-plugin/commands/memory-stats.md +34 -0
- package/.claude-plugin/hooks.json +59 -0
- package/.claude-plugin/plugin.json +24 -0
- package/.history/package_20260201112328.json +45 -0
- package/.history/package_20260201113602.json +45 -0
- package/.history/package_20260201113713.json +45 -0
- package/.history/package_20260201114110.json +45 -0
- package/Memo.txt +558 -0
- package/README.md +520 -0
- package/context.md +636 -0
- package/dist/.claude-plugin/commands/memory-forget.md +42 -0
- package/dist/.claude-plugin/commands/memory-history.md +34 -0
- package/dist/.claude-plugin/commands/memory-import.md +56 -0
- package/dist/.claude-plugin/commands/memory-list.md +37 -0
- package/dist/.claude-plugin/commands/memory-search.md +36 -0
- package/dist/.claude-plugin/commands/memory-stats.md +34 -0
- package/dist/.claude-plugin/hooks.json +59 -0
- package/dist/.claude-plugin/plugin.json +24 -0
- package/dist/cli/index.js +3539 -0
- package/dist/cli/index.js.map +7 -0
- package/dist/core/index.js +4408 -0
- package/dist/core/index.js.map +7 -0
- package/dist/hooks/session-end.js +2971 -0
- package/dist/hooks/session-end.js.map +7 -0
- package/dist/hooks/session-start.js +2969 -0
- package/dist/hooks/session-start.js.map +7 -0
- package/dist/hooks/stop.js +3123 -0
- package/dist/hooks/stop.js.map +7 -0
- package/dist/hooks/user-prompt-submit.js +2960 -0
- package/dist/hooks/user-prompt-submit.js.map +7 -0
- package/dist/services/memory-service.js +2931 -0
- package/dist/services/memory-service.js.map +7 -0
- package/package.json +45 -0
- package/plan.md +1642 -0
- package/scripts/build.ts +102 -0
- package/spec.md +624 -0
- package/specs/citations-system/context.md +243 -0
- package/specs/citations-system/plan.md +495 -0
- package/specs/citations-system/spec.md +371 -0
- package/specs/endless-mode/context.md +305 -0
- package/specs/endless-mode/plan.md +620 -0
- package/specs/endless-mode/spec.md +455 -0
- package/specs/entity-edge-model/context.md +401 -0
- package/specs/entity-edge-model/plan.md +459 -0
- package/specs/entity-edge-model/spec.md +391 -0
- package/specs/evidence-aligner-v2/context.md +401 -0
- package/specs/evidence-aligner-v2/plan.md +303 -0
- package/specs/evidence-aligner-v2/spec.md +312 -0
- package/specs/mcp-desktop-integration/context.md +278 -0
- package/specs/mcp-desktop-integration/plan.md +550 -0
- package/specs/mcp-desktop-integration/spec.md +494 -0
- package/specs/post-tool-use-hook/context.md +319 -0
- package/specs/post-tool-use-hook/plan.md +469 -0
- package/specs/post-tool-use-hook/spec.md +364 -0
- package/specs/private-tags/context.md +288 -0
- package/specs/private-tags/plan.md +412 -0
- package/specs/private-tags/spec.md +345 -0
- package/specs/progressive-disclosure/context.md +346 -0
- package/specs/progressive-disclosure/plan.md +663 -0
- package/specs/progressive-disclosure/spec.md +415 -0
- package/specs/task-entity-system/context.md +297 -0
- package/specs/task-entity-system/plan.md +301 -0
- package/specs/task-entity-system/spec.md +314 -0
- package/specs/vector-outbox-v2/context.md +470 -0
- package/specs/vector-outbox-v2/plan.md +562 -0
- package/specs/vector-outbox-v2/spec.md +466 -0
- package/specs/web-viewer-ui/context.md +384 -0
- package/specs/web-viewer-ui/plan.md +797 -0
- package/specs/web-viewer-ui/spec.md +516 -0
- package/src/cli/index.ts +570 -0
- package/src/core/canonical-key.ts +186 -0
- package/src/core/citation-generator.ts +63 -0
- package/src/core/consolidated-store.ts +279 -0
- package/src/core/consolidation-worker.ts +384 -0
- package/src/core/context-formatter.ts +276 -0
- package/src/core/continuity-manager.ts +336 -0
- package/src/core/edge-repo.ts +324 -0
- package/src/core/embedder.ts +124 -0
- package/src/core/entity-repo.ts +342 -0
- package/src/core/event-store.ts +672 -0
- package/src/core/evidence-aligner.ts +635 -0
- package/src/core/graduation.ts +365 -0
- package/src/core/index.ts +32 -0
- package/src/core/matcher.ts +210 -0
- package/src/core/metadata-extractor.ts +203 -0
- package/src/core/privacy/filter.ts +179 -0
- package/src/core/privacy/index.ts +20 -0
- package/src/core/privacy/tag-parser.ts +145 -0
- package/src/core/progressive-retriever.ts +415 -0
- package/src/core/retriever.ts +235 -0
- package/src/core/task/blocker-resolver.ts +325 -0
- package/src/core/task/index.ts +9 -0
- package/src/core/task/task-matcher.ts +238 -0
- package/src/core/task/task-projector.ts +345 -0
- package/src/core/task/task-resolver.ts +414 -0
- package/src/core/types.ts +841 -0
- package/src/core/vector-outbox.ts +295 -0
- package/src/core/vector-store.ts +182 -0
- package/src/core/vector-worker.ts +488 -0
- package/src/core/working-set-store.ts +244 -0
- package/src/hooks/post-tool-use.ts +127 -0
- package/src/hooks/session-end.ts +78 -0
- package/src/hooks/session-start.ts +57 -0
- package/src/hooks/stop.ts +78 -0
- package/src/hooks/user-prompt-submit.ts +54 -0
- package/src/mcp/handlers.ts +212 -0
- package/src/mcp/index.ts +47 -0
- package/src/mcp/tools.ts +78 -0
- package/src/server/api/citations.ts +101 -0
- package/src/server/api/events.ts +101 -0
- package/src/server/api/index.ts +18 -0
- package/src/server/api/search.ts +98 -0
- package/src/server/api/sessions.ts +111 -0
- package/src/server/api/stats.ts +97 -0
- package/src/server/index.ts +91 -0
- package/src/services/memory-service.ts +626 -0
- package/src/services/session-history-importer.ts +367 -0
- package/tests/canonical-key.test.ts +101 -0
- package/tests/evidence-aligner.test.ts +152 -0
- package/tests/matcher.test.ts +112 -0
- package/tsconfig.json +24 -0
- package/vitest.config.ts +15 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
# Endless Mode Specification
|
|
2
|
+
|
|
3
|
+
> **Version**: 1.0.0
|
|
4
|
+
> **Status**: Draft
|
|
5
|
+
> **Created**: 2026-02-01
|
|
6
|
+
> **Reference**: claude-mem (thedotmack/claude-mem)
|
|
7
|
+
|
|
8
|
+
## 1. 개요
|
|
9
|
+
|
|
10
|
+
### 1.1 문제 정의
|
|
11
|
+
|
|
12
|
+
현재 세션 기반 메모리의 한계:
|
|
13
|
+
|
|
14
|
+
1. **세션 경계**: 세션이 끝나면 컨텍스트 단절
|
|
15
|
+
2. **재시작 비용**: 새 세션마다 컨텍스트 재구성 필요
|
|
16
|
+
3. **연속성 부족**: 장기 프로젝트에서 연속적 학습 어려움
|
|
17
|
+
|
|
18
|
+
### 1.2 해결 방향
|
|
19
|
+
|
|
20
|
+
**Endless Mode (연속 세션)**:
|
|
21
|
+
- 세션 경계 없는 연속적 메모리 스트림
|
|
22
|
+
- Biomimetic Memory Architecture (생체 모방 기억 구조)
|
|
23
|
+
- 자동 컨텍스트 연속성 유지
|
|
24
|
+
|
|
25
|
+
## 2. 핵심 개념
|
|
26
|
+
|
|
27
|
+
### 2.1 Biomimetic Memory Architecture
|
|
28
|
+
|
|
29
|
+
인간 기억 시스템에서 영감:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
33
|
+
│ Human Memory Model │
|
|
34
|
+
├─────────────────────────────────────────────────────────────┤
|
|
35
|
+
│ Sensory Memory → Working Memory → Long-term Memory │
|
|
36
|
+
│ (즉각적) (단기) (장기) │
|
|
37
|
+
└─────────────────────────────────────────────────────────────┘
|
|
38
|
+
↓
|
|
39
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
40
|
+
│ Endless Mode Memory │
|
|
41
|
+
├─────────────────────────────────────────────────────────────┤
|
|
42
|
+
│ Event Stream → Active Context → Consolidated Memory │
|
|
43
|
+
│ (L0 Events) (Working Set) (L4 Memories) │
|
|
44
|
+
└─────────────────────────────────────────────────────────────┘
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2.2 세션 vs Endless
|
|
48
|
+
|
|
49
|
+
| 기존 세션 모드 | Endless Mode |
|
|
50
|
+
|---------------|-------------|
|
|
51
|
+
| 명확한 시작/끝 | 연속적 스트림 |
|
|
52
|
+
| 세션별 요약 | 점진적 통합 |
|
|
53
|
+
| 재시작 시 빈 상태 | 이전 컨텍스트 유지 |
|
|
54
|
+
| session_end 훅 | 백그라운드 통합 |
|
|
55
|
+
|
|
56
|
+
### 2.3 모드 전환
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
enum MemoryMode {
|
|
60
|
+
SESSION = 'session', // 기존 세션 기반
|
|
61
|
+
ENDLESS = 'endless' // 연속 모드
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 3. 아키텍처
|
|
66
|
+
|
|
67
|
+
### 3.1 레이어 구조
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
71
|
+
│ Layer 0: Event Stream (Raw) │
|
|
72
|
+
│ - 모든 이벤트 즉시 기록 │
|
|
73
|
+
│ - 변환/필터 없음 │
|
|
74
|
+
│ - TTL: 무제한 │
|
|
75
|
+
└──────────────────────────────────────────┬──────────────────┘
|
|
76
|
+
│
|
|
77
|
+
(Background)
|
|
78
|
+
│
|
|
79
|
+
┌──────────────────────────────────────────▼──────────────────┐
|
|
80
|
+
│ Layer 1: Working Set (Active Context) │
|
|
81
|
+
│ - 최근 N개 이벤트 │
|
|
82
|
+
│ - 현재 작업 관련 메모리 │
|
|
83
|
+
│ - TTL: 24시간 (sliding) │
|
|
84
|
+
└──────────────────────────────────────────┬──────────────────┘
|
|
85
|
+
│
|
|
86
|
+
(Consolidation)
|
|
87
|
+
│
|
|
88
|
+
┌──────────────────────────────────────────▼──────────────────┐
|
|
89
|
+
│ Layer 2: Consolidated Memory (Long-term) │
|
|
90
|
+
│ - 통합/요약된 지식 │
|
|
91
|
+
│ - 패턴 및 인사이트 │
|
|
92
|
+
│ - TTL: 무제한 │
|
|
93
|
+
└─────────────────────────────────────────────────────────────┘
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 3.2 Working Set 관리
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
interface WorkingSet {
|
|
100
|
+
// 최근 이벤트
|
|
101
|
+
recentEvents: Event[]; // 최근 100개
|
|
102
|
+
recentTimeWindow: number; // 최근 24시간
|
|
103
|
+
|
|
104
|
+
// 활성 컨텍스트
|
|
105
|
+
activeTopics: Topic[]; // 현재 다루는 주제
|
|
106
|
+
activeFiles: string[]; // 최근 접근 파일
|
|
107
|
+
activeEntities: Entity[]; // 관련 엔티티
|
|
108
|
+
|
|
109
|
+
// 메타데이터
|
|
110
|
+
lastActivity: Date;
|
|
111
|
+
continuityScore: number; // 연속성 점수
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 3.3 Consolidation Process
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
interface ConsolidationConfig {
|
|
119
|
+
// 트리거 조건
|
|
120
|
+
triggerInterval: number; // 1시간마다
|
|
121
|
+
triggerEventCount: number; // 100개 이벤트마다
|
|
122
|
+
triggerIdleTime: number; // 30분 유휴 후
|
|
123
|
+
|
|
124
|
+
// 통합 규칙
|
|
125
|
+
minEventsToConsolidate: number; // 최소 10개
|
|
126
|
+
maxConsolidatedSize: number; // 최대 1000자 요약
|
|
127
|
+
preserveHighConfidence: boolean;// 고신뢰도 원본 유지
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## 4. 컨텍스트 연속성
|
|
132
|
+
|
|
133
|
+
### 4.1 연속성 점수
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
function calculateContinuityScore(
|
|
137
|
+
currentContext: Context,
|
|
138
|
+
previousContext: Context
|
|
139
|
+
): number {
|
|
140
|
+
let score = 0;
|
|
141
|
+
|
|
142
|
+
// 주제 연속성
|
|
143
|
+
const topicOverlap = intersection(
|
|
144
|
+
currentContext.topics,
|
|
145
|
+
previousContext.topics
|
|
146
|
+
).length;
|
|
147
|
+
score += topicOverlap * 0.3;
|
|
148
|
+
|
|
149
|
+
// 파일 연속성
|
|
150
|
+
const fileOverlap = intersection(
|
|
151
|
+
currentContext.files,
|
|
152
|
+
previousContext.files
|
|
153
|
+
).length;
|
|
154
|
+
score += fileOverlap * 0.2;
|
|
155
|
+
|
|
156
|
+
// 시간 근접성
|
|
157
|
+
const timeDiff = currentContext.timestamp - previousContext.timestamp;
|
|
158
|
+
const timeScore = Math.exp(-timeDiff / (24 * 60 * 60 * 1000));
|
|
159
|
+
score += timeScore * 0.3;
|
|
160
|
+
|
|
161
|
+
// 엔티티 연속성
|
|
162
|
+
const entityOverlap = intersection(
|
|
163
|
+
currentContext.entities,
|
|
164
|
+
previousContext.entities
|
|
165
|
+
).length;
|
|
166
|
+
score += entityOverlap * 0.2;
|
|
167
|
+
|
|
168
|
+
return Math.min(score, 1.0);
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 4.2 컨텍스트 주입
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
async function injectEndlessContext(
|
|
176
|
+
currentPrompt: string
|
|
177
|
+
): Promise<string> {
|
|
178
|
+
const workingSet = await getWorkingSet();
|
|
179
|
+
|
|
180
|
+
// 연속성 점수 기반 컨텍스트 선택
|
|
181
|
+
const relevantContext = workingSet.recentEvents
|
|
182
|
+
.filter(e => e.relevanceScore >= 0.7)
|
|
183
|
+
.slice(0, 10);
|
|
184
|
+
|
|
185
|
+
// 통합된 메모리에서 관련 항목
|
|
186
|
+
const consolidatedContext = await searchConsolidatedMemory(
|
|
187
|
+
currentPrompt,
|
|
188
|
+
{ topK: 3 }
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
return formatEndlessContext({
|
|
192
|
+
workingSet: relevantContext,
|
|
193
|
+
consolidated: consolidatedContext,
|
|
194
|
+
continuityScore: workingSet.continuityScore
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## 5. 통합 (Consolidation) 프로세스
|
|
200
|
+
|
|
201
|
+
### 5.1 자동 통합
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
class ConsolidationWorker {
|
|
205
|
+
private running = false;
|
|
206
|
+
|
|
207
|
+
async start(): Promise<void> {
|
|
208
|
+
this.running = true;
|
|
209
|
+
|
|
210
|
+
while (this.running) {
|
|
211
|
+
await this.checkAndConsolidate();
|
|
212
|
+
await sleep(this.config.triggerInterval);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private async checkAndConsolidate(): Promise<void> {
|
|
217
|
+
const workingSet = await getWorkingSet();
|
|
218
|
+
|
|
219
|
+
// 트리거 조건 확인
|
|
220
|
+
if (this.shouldConsolidate(workingSet)) {
|
|
221
|
+
await this.consolidate(workingSet);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private shouldConsolidate(workingSet: WorkingSet): boolean {
|
|
226
|
+
// 이벤트 수 기준
|
|
227
|
+
if (workingSet.recentEvents.length >= this.config.triggerEventCount) {
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// 유휴 시간 기준
|
|
232
|
+
const idleTime = Date.now() - workingSet.lastActivity.getTime();
|
|
233
|
+
if (idleTime >= this.config.triggerIdleTime) {
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
private async consolidate(workingSet: WorkingSet): Promise<void> {
|
|
241
|
+
// 1. 관련 이벤트 그룹화
|
|
242
|
+
const groups = groupByTopic(workingSet.recentEvents);
|
|
243
|
+
|
|
244
|
+
// 2. 각 그룹 요약
|
|
245
|
+
for (const group of groups) {
|
|
246
|
+
const summary = await summarizeGroup(group);
|
|
247
|
+
|
|
248
|
+
// 3. 통합 메모리에 저장
|
|
249
|
+
await storeConsolidatedMemory({
|
|
250
|
+
summary,
|
|
251
|
+
sourceEvents: group.map(e => e.eventId),
|
|
252
|
+
topics: group.topics,
|
|
253
|
+
confidence: calculateGroupConfidence(group)
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// 4. Working Set 정리
|
|
258
|
+
await pruneWorkingSet(workingSet);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### 5.2 요약 생성
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
async function summarizeGroup(events: Event[]): Promise<string> {
|
|
267
|
+
// 옵션 1: 로컬 규칙 기반
|
|
268
|
+
if (events.length < 5) {
|
|
269
|
+
return extractKeyPoints(events);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// 옵션 2: LLM 기반 (비용 발생)
|
|
273
|
+
if (config.useLLMSummarization) {
|
|
274
|
+
return await llmSummarize(events);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// 옵션 3: 하이브리드
|
|
278
|
+
const keyPoints = extractKeyPoints(events);
|
|
279
|
+
return formatSummary(keyPoints);
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## 6. 데이터 스키마
|
|
284
|
+
|
|
285
|
+
### 6.1 Working Set 테이블
|
|
286
|
+
|
|
287
|
+
```sql
|
|
288
|
+
CREATE TABLE working_set (
|
|
289
|
+
id VARCHAR PRIMARY KEY,
|
|
290
|
+
event_id VARCHAR NOT NULL REFERENCES events(event_id),
|
|
291
|
+
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
292
|
+
relevance_score FLOAT,
|
|
293
|
+
topics JSON,
|
|
294
|
+
expires_at TIMESTAMP
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
CREATE INDEX idx_working_set_expires ON working_set(expires_at);
|
|
298
|
+
CREATE INDEX idx_working_set_relevance ON working_set(relevance_score DESC);
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### 6.2 Consolidated Memory 테이블
|
|
302
|
+
|
|
303
|
+
```sql
|
|
304
|
+
CREATE TABLE consolidated_memories (
|
|
305
|
+
memory_id VARCHAR PRIMARY KEY,
|
|
306
|
+
summary TEXT NOT NULL,
|
|
307
|
+
topics JSON,
|
|
308
|
+
source_events JSON, -- 원본 이벤트 ID 목록
|
|
309
|
+
confidence FLOAT,
|
|
310
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
311
|
+
accessed_at TIMESTAMP,
|
|
312
|
+
access_count INTEGER DEFAULT 0
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
CREATE INDEX idx_consolidated_confidence ON consolidated_memories(confidence DESC);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### 6.3 Continuity Log 테이블
|
|
319
|
+
|
|
320
|
+
```sql
|
|
321
|
+
CREATE TABLE continuity_log (
|
|
322
|
+
log_id VARCHAR PRIMARY KEY,
|
|
323
|
+
from_context_id VARCHAR,
|
|
324
|
+
to_context_id VARCHAR,
|
|
325
|
+
continuity_score FLOAT,
|
|
326
|
+
transition_type VARCHAR, -- 'seamless' | 'topic_shift' | 'break'
|
|
327
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
328
|
+
);
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## 7. 설정
|
|
332
|
+
|
|
333
|
+
### 7.1 Endless Mode 설정
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
const EndlessModeConfigSchema = z.object({
|
|
337
|
+
enabled: z.boolean().default(false),
|
|
338
|
+
|
|
339
|
+
workingSet: z.object({
|
|
340
|
+
maxEvents: z.number().default(100),
|
|
341
|
+
timeWindowHours: z.number().default(24),
|
|
342
|
+
minRelevanceScore: z.number().default(0.5)
|
|
343
|
+
}),
|
|
344
|
+
|
|
345
|
+
consolidation: z.object({
|
|
346
|
+
triggerIntervalMs: z.number().default(3600000), // 1시간
|
|
347
|
+
triggerEventCount: z.number().default(100),
|
|
348
|
+
triggerIdleMs: z.number().default(1800000), // 30분
|
|
349
|
+
useLLMSummarization: z.boolean().default(false)
|
|
350
|
+
}),
|
|
351
|
+
|
|
352
|
+
continuity: z.object({
|
|
353
|
+
minScoreForSeamless: z.number().default(0.7),
|
|
354
|
+
topicDecayHours: z.number().default(48)
|
|
355
|
+
})
|
|
356
|
+
});
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### 7.2 모드 전환
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
# Endless Mode 활성화
|
|
363
|
+
$ code-memory config set mode endless
|
|
364
|
+
|
|
365
|
+
# Session Mode로 복귀
|
|
366
|
+
$ code-memory config set mode session
|
|
367
|
+
|
|
368
|
+
# 현재 모드 확인
|
|
369
|
+
$ code-memory config get mode
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
## 8. UI 표시
|
|
373
|
+
|
|
374
|
+
### 8.1 CLI 상태
|
|
375
|
+
|
|
376
|
+
```
|
|
377
|
+
$ code-memory status
|
|
378
|
+
|
|
379
|
+
Mode: Endless
|
|
380
|
+
Working Set: 47 events (last 18 hours)
|
|
381
|
+
Continuity Score: 0.85 (seamless)
|
|
382
|
+
Consolidated: 23 memories
|
|
383
|
+
Last Consolidation: 2 hours ago
|
|
384
|
+
|
|
385
|
+
Active Topics:
|
|
386
|
+
- DuckDB schema design
|
|
387
|
+
- Event sourcing pattern
|
|
388
|
+
- TypeScript types
|
|
389
|
+
|
|
390
|
+
Recent Files:
|
|
391
|
+
- src/core/event-store.ts
|
|
392
|
+
- src/core/types.ts
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### 8.2 Web Viewer
|
|
396
|
+
|
|
397
|
+
```
|
|
398
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
399
|
+
│ Endless Mode Dashboard │
|
|
400
|
+
├─────────────────────────────────────────────────────────────┤
|
|
401
|
+
│ │
|
|
402
|
+
│ ┌─────────────────┐ ┌─────────────────┐ │
|
|
403
|
+
│ │ Continuity │ │ Working Set │ │
|
|
404
|
+
│ │ 0.85 │ │ 47 events │ │
|
|
405
|
+
│ │ ████████░░ │ │ 18 hours │ │
|
|
406
|
+
│ │ Seamless │ └─────────────────┘ │
|
|
407
|
+
│ └─────────────────┘ │
|
|
408
|
+
│ │
|
|
409
|
+
│ Timeline (Continuous) │
|
|
410
|
+
│ ──────────────────────────────────────────────────────────│
|
|
411
|
+
│ │ │ │ │ │ │ │ │ │ │ │ │
|
|
412
|
+
│ └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ │
|
|
413
|
+
│ -24h -12h now │
|
|
414
|
+
│ │
|
|
415
|
+
│ Consolidated Memories (23) │
|
|
416
|
+
│ ───────────────────────────────────────────────────────── │
|
|
417
|
+
│ 📝 DuckDB 스키마 설계 결정 (confidence: 0.92) │
|
|
418
|
+
│ 📝 이벤트 소싱 패턴 구현 (confidence: 0.88) │
|
|
419
|
+
│ 📝 타입 시스템 리팩토링 (confidence: 0.85) │
|
|
420
|
+
│ │
|
|
421
|
+
└─────────────────────────────────────────────────────────────┘
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
## 9. 마이그레이션
|
|
425
|
+
|
|
426
|
+
### 9.1 Session → Endless 전환
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
async function migrateToEndless(): Promise<void> {
|
|
430
|
+
// 1. 기존 세션 데이터 유지
|
|
431
|
+
// 2. Working Set 초기화
|
|
432
|
+
const recentSessions = await getRecentSessions(7); // 최근 7일
|
|
433
|
+
|
|
434
|
+
for (const session of recentSessions) {
|
|
435
|
+
const events = await getSessionEvents(session.id);
|
|
436
|
+
await addToWorkingSet(events);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// 3. 초기 통합 실행
|
|
440
|
+
await runInitialConsolidation();
|
|
441
|
+
|
|
442
|
+
// 4. 모드 변경
|
|
443
|
+
await setConfig('mode', 'endless');
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## 10. 성공 기준
|
|
448
|
+
|
|
449
|
+
- [ ] Endless Mode 활성화/비활성화 전환 가능
|
|
450
|
+
- [ ] Working Set이 24시간 슬라이딩 윈도우로 유지
|
|
451
|
+
- [ ] 자동 Consolidation이 백그라운드에서 실행
|
|
452
|
+
- [ ] 연속성 점수가 정확히 계산됨
|
|
453
|
+
- [ ] 세션 재시작 시 이전 컨텍스트 자동 로드
|
|
454
|
+
- [ ] Web Viewer에서 Endless Mode 대시보드 표시
|
|
455
|
+
- [ ] 기존 Session Mode와 호환 유지
|