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
package/spec.md
ADDED
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
# Specification: Claude Code Memory Plugin
|
|
2
|
+
|
|
3
|
+
## 1. 개요
|
|
4
|
+
|
|
5
|
+
### 1.1 플러그인 정보
|
|
6
|
+
|
|
7
|
+
| 항목 | 값 |
|
|
8
|
+
|------|-----|
|
|
9
|
+
| **이름** | `code-memory` |
|
|
10
|
+
| **버전** | `1.0.0` |
|
|
11
|
+
| **설명** | 대화 기억을 통해 사용자 맞춤형 경험을 제공하는 Claude Code 플러그인 |
|
|
12
|
+
| **핵심 가치** | "사용할수록 똑똑해지는 Agent" |
|
|
13
|
+
|
|
14
|
+
### 1.2 핵심 기능
|
|
15
|
+
|
|
16
|
+
1. **대화 기억 저장**: 모든 사용자 prompt와 agent 응답을 영구 저장
|
|
17
|
+
2. **지능형 검색**: 새로운 prompt와 관련된 과거 기억을 의미 기반 검색
|
|
18
|
+
3. **컨텍스트 주입**: 관련 기억을 현재 대화에 자동 주입
|
|
19
|
+
4. **학습 및 진화**: 패턴 인식을 통한 개인화
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. 아키텍처
|
|
24
|
+
|
|
25
|
+
### 2.1 시스템 구조
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
29
|
+
│ Claude Code Session │
|
|
30
|
+
└─────────────────────────────────────────────────────────────┘
|
|
31
|
+
│ │ │
|
|
32
|
+
▼ ▼ ▼
|
|
33
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
34
|
+
│ SessionStart│ │UserPrompt │ │ Stop/ │
|
|
35
|
+
│ Hook │ │Submit Hook │ │ SessionEnd │
|
|
36
|
+
└─────────────┘ └─────────────┘ └─────────────┘
|
|
37
|
+
│ │ │
|
|
38
|
+
▼ ▼ ▼
|
|
39
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
40
|
+
│ Memory Service (Core) │
|
|
41
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
42
|
+
│ │ Ingester │ │ Embedder │ │ Retriever│ │ Ranker │ │
|
|
43
|
+
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
44
|
+
└─────────────────────────────────────────────────────────────┘
|
|
45
|
+
│ │ │
|
|
46
|
+
▼ ▼ ▼
|
|
47
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
48
|
+
│ Storage Layer │
|
|
49
|
+
│ ┌───────────────────┐ ┌───────────────────┐ │
|
|
50
|
+
│ │ LanceDB │ │ DuckDB │ │
|
|
51
|
+
│ │ (Vector Store) │ │ (Event Store) │ │
|
|
52
|
+
│ └───────────────────┘ └───────────────────┘ │
|
|
53
|
+
└─────────────────────────────────────────────────────────────┘
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 2.2 데이터 흐름
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
1. [SessionStart]
|
|
60
|
+
→ 이전 세션 요약 로드
|
|
61
|
+
→ 사용자 선호도/패턴 로드
|
|
62
|
+
|
|
63
|
+
2. [UserPromptSubmit]
|
|
64
|
+
→ 현재 prompt 임베딩 생성
|
|
65
|
+
→ 관련 기억 검색 (top-k)
|
|
66
|
+
→ 기억을 시스템 프롬프트로 주입
|
|
67
|
+
|
|
68
|
+
3. [Stop/AgentResponse]
|
|
69
|
+
→ 전체 대화 쌍 (prompt + response) 저장
|
|
70
|
+
→ 비동기 임베딩 생성 및 인덱싱
|
|
71
|
+
|
|
72
|
+
4. [SessionEnd]
|
|
73
|
+
→ 세션 요약 생성 및 저장
|
|
74
|
+
→ 장기 기억으로 통합
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 2.3 Memory Graduation Pipeline (L0 → L4)
|
|
78
|
+
|
|
79
|
+
AXIOMMIND 기반 다단계 메모리 승격 구조:
|
|
80
|
+
|
|
81
|
+
| 레벨 | 이름 | 설명 | 저장소 | 상태 |
|
|
82
|
+
|------|------|------|--------|------|
|
|
83
|
+
| **L0** | EventStore | 원본 대화 로그 (불변) | DuckDB `events` | 즉시 저장 |
|
|
84
|
+
| **L1** | Structured | LLM 추출 구조화 데이터 | DuckDB `insights` | 비동기 처리 |
|
|
85
|
+
| **L2** | Candidates | 타입 검증 대상 | TypeScript 검증 | 배치 처리 |
|
|
86
|
+
| **L3** | Verified | 검증 완료 지식 | DuckDB `verified_knowledge` | 검증 후 |
|
|
87
|
+
| **L4** | Active | 검색 가능 메모리 | LanceDB | 인덱싱 후 |
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
User Prompt → L0 (즉시) → L1 (비동기) → L2 (배치) → L3 (검증) → L4 (검색 가능)
|
|
91
|
+
↑ ↓
|
|
92
|
+
└──────────── 검색 시 L4에서 조회 ─────────────┘
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 2.4 AXIOMMIND 7가지 필수 원칙
|
|
96
|
+
|
|
97
|
+
본 플러그인은 다음 원칙을 준수합니다:
|
|
98
|
+
|
|
99
|
+
| # | 원칙 | 구현 |
|
|
100
|
+
|---|------|------|
|
|
101
|
+
| 1 | 진실의 원천은 이벤트 로그 | `events` 테이블에서 모든 파생 데이터 재구성 가능 |
|
|
102
|
+
| 2 | 추가전용 구조 | `EventStore.append()` 만 제공, UPDATE/DELETE 없음 |
|
|
103
|
+
| 3 | 멱등성 보장 | `dedupe_key = session_id + content_hash` |
|
|
104
|
+
| 4 | 증거 범위는 파이프라인이 확정 | `EvidenceAligner`가 정확한 스팬 계산 |
|
|
105
|
+
| 5 | Task는 엔티티 | `canonical_key`로 동일 개념 통합 |
|
|
106
|
+
| 6 | 벡터 저장소 정합성 | DuckDB → outbox → LanceDB 단방향 |
|
|
107
|
+
| 7 | DuckDB JSON 사용 | JSONB 대신 표준 JSON |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 3. 데이터 모델
|
|
112
|
+
|
|
113
|
+
### 3.1 Event Schema (DuckDB) - AXIOMMIND 스타일
|
|
114
|
+
|
|
115
|
+
```sql
|
|
116
|
+
-- ============================================================
|
|
117
|
+
-- L0 EventStore: Single Source of Truth (불변, append-only)
|
|
118
|
+
-- ============================================================
|
|
119
|
+
|
|
120
|
+
CREATE TABLE events (
|
|
121
|
+
id UUID PRIMARY KEY,
|
|
122
|
+
event_type VARCHAR NOT NULL, -- 'user_prompt' | 'agent_response' | 'session_summary'
|
|
123
|
+
session_id VARCHAR NOT NULL,
|
|
124
|
+
timestamp TIMESTAMP NOT NULL,
|
|
125
|
+
content TEXT NOT NULL,
|
|
126
|
+
canonical_key VARCHAR NOT NULL, -- 정규화된 키 (NFKC, lowercase, no punctuation)
|
|
127
|
+
metadata JSON,
|
|
128
|
+
dedupe_key VARCHAR UNIQUE -- 멱등성 보장 (content_hash + session_id)
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
-- 중복 방지 테이블 (event_dedup)
|
|
132
|
+
CREATE TABLE event_dedup (
|
|
133
|
+
dedupe_key VARCHAR PRIMARY KEY,
|
|
134
|
+
event_id UUID NOT NULL REFERENCES events(id),
|
|
135
|
+
created_at TIMESTAMP DEFAULT NOW()
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
-- Projection offset 추적 (증분 처리용)
|
|
139
|
+
CREATE TABLE projection_offsets (
|
|
140
|
+
projection_name VARCHAR PRIMARY KEY,
|
|
141
|
+
last_event_id UUID,
|
|
142
|
+
last_timestamp TIMESTAMP,
|
|
143
|
+
updated_at TIMESTAMP DEFAULT NOW()
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
-- ============================================================
|
|
147
|
+
-- 세션 메타데이터
|
|
148
|
+
-- ============================================================
|
|
149
|
+
|
|
150
|
+
CREATE TABLE sessions (
|
|
151
|
+
id VARCHAR PRIMARY KEY,
|
|
152
|
+
started_at TIMESTAMP NOT NULL,
|
|
153
|
+
ended_at TIMESTAMP,
|
|
154
|
+
project_path VARCHAR,
|
|
155
|
+
summary TEXT,
|
|
156
|
+
tags JSON
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
-- ============================================================
|
|
160
|
+
-- 추출된 인사이트 (파생 데이터, 재구성 가능)
|
|
161
|
+
-- ============================================================
|
|
162
|
+
|
|
163
|
+
CREATE TABLE insights (
|
|
164
|
+
id UUID PRIMARY KEY,
|
|
165
|
+
insight_type VARCHAR NOT NULL, -- 'preference' | 'pattern' | 'expertise'
|
|
166
|
+
content TEXT NOT NULL,
|
|
167
|
+
canonical_key VARCHAR NOT NULL, -- 정규화된 키
|
|
168
|
+
confidence FLOAT,
|
|
169
|
+
source_events JSON, -- 원본 이벤트 ID 목록
|
|
170
|
+
created_at TIMESTAMP,
|
|
171
|
+
last_updated TIMESTAMP
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
-- ============================================================
|
|
175
|
+
-- Embedding Outbox (Single-Writer Pattern)
|
|
176
|
+
-- ============================================================
|
|
177
|
+
|
|
178
|
+
CREATE TABLE embedding_outbox (
|
|
179
|
+
id UUID PRIMARY KEY,
|
|
180
|
+
event_id UUID NOT NULL REFERENCES events(id),
|
|
181
|
+
content TEXT NOT NULL,
|
|
182
|
+
status VARCHAR DEFAULT 'pending', -- 'pending' | 'processing' | 'done' | 'failed'
|
|
183
|
+
retry_count INT DEFAULT 0,
|
|
184
|
+
created_at TIMESTAMP DEFAULT NOW(),
|
|
185
|
+
processed_at TIMESTAMP,
|
|
186
|
+
error_message TEXT
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
-- ============================================================
|
|
190
|
+
-- Memory Resolutions (Condition → Task 해결)
|
|
191
|
+
-- ============================================================
|
|
192
|
+
|
|
193
|
+
CREATE TABLE memory_resolutions (
|
|
194
|
+
id UUID PRIMARY KEY,
|
|
195
|
+
condition_id UUID NOT NULL, -- 원본 조건/참조
|
|
196
|
+
resolved_to_id UUID, -- 해결된 대상
|
|
197
|
+
resolution_type VARCHAR, -- 'confirmed' | 'rejected' | 'pending'
|
|
198
|
+
confidence FLOAT,
|
|
199
|
+
resolved_at TIMESTAMP
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
-- ============================================================
|
|
203
|
+
-- Effective View (Condition 해결 반영)
|
|
204
|
+
-- ============================================================
|
|
205
|
+
|
|
206
|
+
CREATE VIEW v_memory_context_effective AS
|
|
207
|
+
SELECT
|
|
208
|
+
e.id,
|
|
209
|
+
e.session_id,
|
|
210
|
+
e.content,
|
|
211
|
+
e.canonical_key,
|
|
212
|
+
e.event_type,
|
|
213
|
+
e.timestamp,
|
|
214
|
+
COALESCE(r.resolved_to_id, e.id) as effective_id,
|
|
215
|
+
CASE
|
|
216
|
+
WHEN r.resolution_type = 'confirmed' THEN 'resolved'
|
|
217
|
+
WHEN r.resolution_type = 'pending' THEN 'pending'
|
|
218
|
+
ELSE 'direct'
|
|
219
|
+
END as resolution_status
|
|
220
|
+
FROM events e
|
|
221
|
+
LEFT JOIN memory_resolutions r ON e.id = r.condition_id;
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### 3.2 Vector Schema (LanceDB)
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
# 대화 임베딩 테이블
|
|
228
|
+
conversations_schema = {
|
|
229
|
+
"id": str, # UUID
|
|
230
|
+
"event_id": str, # events 테이블 참조
|
|
231
|
+
"session_id": str,
|
|
232
|
+
"event_type": str, # 'user_prompt' | 'agent_response'
|
|
233
|
+
"content": str, # 원본 텍스트 (검색 결과 표시용)
|
|
234
|
+
"vector": list[float], # 임베딩 벡터 (384 또는 1536 차원)
|
|
235
|
+
"timestamp": str,
|
|
236
|
+
"metadata": dict # 추가 메타데이터
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
# 인사이트 임베딩 테이블
|
|
240
|
+
insights_schema = {
|
|
241
|
+
"id": str,
|
|
242
|
+
"insight_id": str, # insights 테이블 참조
|
|
243
|
+
"content": str,
|
|
244
|
+
"vector": list[float],
|
|
245
|
+
"insight_type": str,
|
|
246
|
+
"confidence": float
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### 3.3 TypeScript 타입 정의 (Idris2 영감)
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
// 불변성과 타입 안전성을 강조한 설계
|
|
254
|
+
|
|
255
|
+
// 이벤트 타입 (Union Type으로 완전성 보장)
|
|
256
|
+
type EventType = 'user_prompt' | 'agent_response' | 'session_summary';
|
|
257
|
+
|
|
258
|
+
// 이벤트 구조 (Readonly로 불변성 강제)
|
|
259
|
+
interface MemoryEvent {
|
|
260
|
+
readonly id: string;
|
|
261
|
+
readonly eventType: EventType;
|
|
262
|
+
readonly sessionId: string;
|
|
263
|
+
readonly timestamp: Date;
|
|
264
|
+
readonly content: string;
|
|
265
|
+
readonly contentHash: string;
|
|
266
|
+
readonly metadata: Readonly<Record<string, unknown>>;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// 검색 결과 (신뢰도 점수 포함)
|
|
270
|
+
interface MemoryMatch {
|
|
271
|
+
readonly event: MemoryEvent;
|
|
272
|
+
readonly score: number; // 0.0 ~ 1.0
|
|
273
|
+
readonly relevanceReason: string;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// 컨텍스트 주입 결과
|
|
277
|
+
interface ContextInjection {
|
|
278
|
+
readonly memories: ReadonlyArray<MemoryMatch>;
|
|
279
|
+
readonly systemPromptAddition: string;
|
|
280
|
+
readonly totalTokensUsed: number;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// 저장 결과 (성공/실패 명시적 표현)
|
|
284
|
+
type SaveResult =
|
|
285
|
+
| { success: true; eventId: string }
|
|
286
|
+
| { success: false; error: string; isDuplicate: boolean };
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## 4. Hook 명세
|
|
292
|
+
|
|
293
|
+
### 4.1 SessionStart Hook
|
|
294
|
+
|
|
295
|
+
**목적**: 세션 시작 시 관련 컨텍스트 로드
|
|
296
|
+
|
|
297
|
+
```json
|
|
298
|
+
{
|
|
299
|
+
"hooks": {
|
|
300
|
+
"SessionStart": [
|
|
301
|
+
{
|
|
302
|
+
"type": "command",
|
|
303
|
+
"command": "code-memory session-start",
|
|
304
|
+
"timeout": 5000
|
|
305
|
+
}
|
|
306
|
+
]
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**입력**:
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
"session_id": "sess_abc123",
|
|
315
|
+
"cwd": "/path/to/project"
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**출력**:
|
|
320
|
+
```json
|
|
321
|
+
{
|
|
322
|
+
"context": "## Previous Session Context\n- Last worked on: API authentication\n- User preference: Prefers TypeScript\n- Recent patterns: Uses Zod for validation"
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### 4.2 UserPromptSubmit Hook
|
|
327
|
+
|
|
328
|
+
**목적**: 사용자 입력 시 관련 기억 검색 및 주입
|
|
329
|
+
|
|
330
|
+
```json
|
|
331
|
+
{
|
|
332
|
+
"hooks": {
|
|
333
|
+
"UserPromptSubmit": [
|
|
334
|
+
{
|
|
335
|
+
"type": "command",
|
|
336
|
+
"command": "code-memory search",
|
|
337
|
+
"timeout": 3000
|
|
338
|
+
}
|
|
339
|
+
]
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**입력**:
|
|
345
|
+
```json
|
|
346
|
+
{
|
|
347
|
+
"session_id": "sess_abc123",
|
|
348
|
+
"prompt": "How do I add rate limiting to the API?"
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
**출력**:
|
|
353
|
+
```json
|
|
354
|
+
{
|
|
355
|
+
"context": "## Relevant Memories\n\n### Previous Discussion (2 weeks ago)\nYou implemented rate limiting for the /users endpoint using express-rate-limit...\n\n### Your Preferences\n- Prefers middleware-based solutions\n- Uses Redis for distributed rate limiting"
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### 4.3 Stop Hook
|
|
360
|
+
|
|
361
|
+
**목적**: Agent 응답 완료 시 대화 저장
|
|
362
|
+
|
|
363
|
+
```json
|
|
364
|
+
{
|
|
365
|
+
"hooks": {
|
|
366
|
+
"Stop": [
|
|
367
|
+
{
|
|
368
|
+
"type": "command",
|
|
369
|
+
"command": "code-memory save",
|
|
370
|
+
"timeout": 5000
|
|
371
|
+
}
|
|
372
|
+
]
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**입력**:
|
|
378
|
+
```json
|
|
379
|
+
{
|
|
380
|
+
"session_id": "sess_abc123",
|
|
381
|
+
"stop_reason": "end_turn",
|
|
382
|
+
"messages": [
|
|
383
|
+
{"role": "user", "content": "..."},
|
|
384
|
+
{"role": "assistant", "content": "..."}
|
|
385
|
+
]
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### 4.4 SessionEnd Hook
|
|
390
|
+
|
|
391
|
+
**목적**: 세션 종료 시 요약 저장
|
|
392
|
+
|
|
393
|
+
```json
|
|
394
|
+
{
|
|
395
|
+
"hooks": {
|
|
396
|
+
"SessionEnd": [
|
|
397
|
+
{
|
|
398
|
+
"type": "command",
|
|
399
|
+
"command": "code-memory session-end",
|
|
400
|
+
"timeout": 10000
|
|
401
|
+
}
|
|
402
|
+
]
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## 5. 명령어 인터페이스
|
|
410
|
+
|
|
411
|
+
### 5.1 슬래시 명령어
|
|
412
|
+
|
|
413
|
+
| 명령어 | 설명 | 예시 |
|
|
414
|
+
|--------|------|------|
|
|
415
|
+
| `/code-memory:search` | 기억 수동 검색 | `/code-memory:search rate limiting` |
|
|
416
|
+
| `/code-memory:history` | 최근 대화 이력 | `/code-memory:history 10` |
|
|
417
|
+
| `/code-memory:insights` | 추출된 인사이트 보기 | `/code-memory:insights` |
|
|
418
|
+
| `/code-memory:forget` | 특정 기억 삭제 | `/code-memory:forget <id>` |
|
|
419
|
+
| `/code-memory:export` | 기억 내보내기 | `/code-memory:export json` |
|
|
420
|
+
| `/code-memory:stats` | 통계 보기 | `/code-memory:stats` |
|
|
421
|
+
|
|
422
|
+
### 5.2 CLI 명령어 (Hook에서 호출)
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
# 세션 시작
|
|
426
|
+
code-memory session-start --session-id <id> --cwd <path>
|
|
427
|
+
|
|
428
|
+
# 기억 검색
|
|
429
|
+
code-memory search --query <text> --limit 5 --threshold 0.7
|
|
430
|
+
|
|
431
|
+
# 대화 저장
|
|
432
|
+
code-memory save --stdin # JSON 입력 수신
|
|
433
|
+
|
|
434
|
+
# 세션 종료
|
|
435
|
+
code-memory session-end --session-id <id>
|
|
436
|
+
|
|
437
|
+
# 데이터베이스 초기화
|
|
438
|
+
code-memory init
|
|
439
|
+
|
|
440
|
+
# 임베딩 재생성
|
|
441
|
+
code-memory reindex
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## 6. 설정
|
|
447
|
+
|
|
448
|
+
### 6.1 plugin.json
|
|
449
|
+
|
|
450
|
+
```json
|
|
451
|
+
{
|
|
452
|
+
"name": "code-memory",
|
|
453
|
+
"description": "Learn from conversations to provide personalized assistance",
|
|
454
|
+
"version": "1.0.0",
|
|
455
|
+
"author": {
|
|
456
|
+
"name": "Buzzni"
|
|
457
|
+
},
|
|
458
|
+
"homepage": "https://github.com/buzzni/code-memory",
|
|
459
|
+
"repository": {
|
|
460
|
+
"type": "git",
|
|
461
|
+
"url": "https://github.com/buzzni/code-memory.git"
|
|
462
|
+
},
|
|
463
|
+
"license": "MIT",
|
|
464
|
+
"engines": {
|
|
465
|
+
"claude-code": ">=1.0.33"
|
|
466
|
+
},
|
|
467
|
+
"keywords": ["memory", "learning", "personalization", "context"]
|
|
468
|
+
}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### 6.2 사용자 설정 (config.json)
|
|
472
|
+
|
|
473
|
+
```json
|
|
474
|
+
{
|
|
475
|
+
"storage": {
|
|
476
|
+
"path": "~/.claude-code/memory",
|
|
477
|
+
"maxSizeMB": 500
|
|
478
|
+
},
|
|
479
|
+
"embedding": {
|
|
480
|
+
"provider": "local", // "local" | "openai"
|
|
481
|
+
"model": "all-MiniLM-L6-v2", // local 모델
|
|
482
|
+
"openaiModel": "text-embedding-3-small",
|
|
483
|
+
"batchSize": 32
|
|
484
|
+
},
|
|
485
|
+
"retrieval": {
|
|
486
|
+
"topK": 5,
|
|
487
|
+
"minScore": 0.7,
|
|
488
|
+
"maxTokens": 2000 // 주입할 최대 토큰 수
|
|
489
|
+
},
|
|
490
|
+
"matching": {
|
|
491
|
+
"minCombinedScore": 0.92, // 확정 매칭 최소 점수 (AXIOMMIND)
|
|
492
|
+
"minGap": 0.03, // 1위-2위 간 최소 점수 차이
|
|
493
|
+
"suggestionThreshold": 0.75, // 제안 모드 임계값
|
|
494
|
+
"weights": {
|
|
495
|
+
"semanticSimilarity": 0.4, // 벡터 유사도 가중치
|
|
496
|
+
"ftsScore": 0.25, // 전문 검색 가중치
|
|
497
|
+
"recencyBonus": 0.2, // 최신성 가산점
|
|
498
|
+
"statusWeight": 0.15 // 상태별 가중치
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
"privacy": {
|
|
502
|
+
"excludePatterns": [ // 저장 제외 패턴
|
|
503
|
+
"password",
|
|
504
|
+
"secret",
|
|
505
|
+
"api_key"
|
|
506
|
+
],
|
|
507
|
+
"anonymize": false
|
|
508
|
+
},
|
|
509
|
+
"features": {
|
|
510
|
+
"autoSave": true,
|
|
511
|
+
"sessionSummary": true,
|
|
512
|
+
"insightExtraction": true,
|
|
513
|
+
"crossProjectLearning": false, // 프로젝트 간 학습
|
|
514
|
+
"singleWriterMode": true // Outbox 패턴 사용 (권장)
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### 6.3 Matching Thresholds (AXIOMMIND 기반)
|
|
520
|
+
|
|
521
|
+
검색 결과의 신뢰도를 3단계로 분류:
|
|
522
|
+
|
|
523
|
+
| 신뢰도 | 조건 | 동작 |
|
|
524
|
+
|--------|------|------|
|
|
525
|
+
| **high** | score ≥ 0.92 AND gap ≥ 0.03 | 확정 매칭, 자동 컨텍스트 주입 |
|
|
526
|
+
| **suggested** | 0.75 ≤ score < 0.92 | 제안 모드, 사용자 확인 권장 |
|
|
527
|
+
| **none** | score < 0.75 | 매칭 없음 |
|
|
528
|
+
|
|
529
|
+
```typescript
|
|
530
|
+
// Matching 결과 타입
|
|
531
|
+
interface MatchResult {
|
|
532
|
+
readonly match: MemoryMatch | null;
|
|
533
|
+
readonly confidence: 'high' | 'suggested' | 'none';
|
|
534
|
+
readonly gap?: number; // top-1과 top-2 간 점수 차이
|
|
535
|
+
readonly alternatives?: ReadonlyArray<MemoryMatch>; // suggested일 때 대안들
|
|
536
|
+
}
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
---
|
|
540
|
+
|
|
541
|
+
## 7. 보안 및 프라이버시
|
|
542
|
+
|
|
543
|
+
### 7.1 데이터 보호
|
|
544
|
+
|
|
545
|
+
1. **로컬 저장**: 모든 데이터는 사용자 로컬에만 저장
|
|
546
|
+
2. **민감 정보 필터링**: password, secret, api_key 등 자동 제외
|
|
547
|
+
3. **선택적 익명화**: 개인 식별 정보 마스킹 옵션
|
|
548
|
+
|
|
549
|
+
### 7.2 데이터 삭제
|
|
550
|
+
|
|
551
|
+
```bash
|
|
552
|
+
# 특정 기억 삭제
|
|
553
|
+
code-memory forget --id <event_id>
|
|
554
|
+
|
|
555
|
+
# 세션 전체 삭제
|
|
556
|
+
code-memory forget --session <session_id>
|
|
557
|
+
|
|
558
|
+
# 기간별 삭제
|
|
559
|
+
code-memory forget --before "2024-01-01"
|
|
560
|
+
|
|
561
|
+
# 전체 초기화
|
|
562
|
+
code-memory reset --confirm
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
---
|
|
566
|
+
|
|
567
|
+
## 8. 성능 요구사항
|
|
568
|
+
|
|
569
|
+
| 항목 | 목표 | 비고 |
|
|
570
|
+
|------|------|------|
|
|
571
|
+
| **검색 지연** | < 500ms | 10만 건 기준 |
|
|
572
|
+
| **저장 지연** | < 100ms | 비동기 처리 |
|
|
573
|
+
| **메모리 사용** | < 200MB | 실행 시 |
|
|
574
|
+
| **디스크 사용** | < 500MB | 기본 제한 |
|
|
575
|
+
| **시작 시간** | < 2s | 세션 시작 |
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
## 9. 의존성
|
|
580
|
+
|
|
581
|
+
### 9.1 런타임 의존성
|
|
582
|
+
|
|
583
|
+
| 패키지 | 버전 | 용도 |
|
|
584
|
+
|--------|------|------|
|
|
585
|
+
| `lancedb` | ^0.5.0 | 벡터 저장소 |
|
|
586
|
+
| `duckdb` | ^0.10.0 | 이벤트 저장소 |
|
|
587
|
+
| `sentence-transformers` | ^2.2.0 | 로컬 임베딩 (Python) |
|
|
588
|
+
| `@xenova/transformers` | ^2.15.0 | 로컬 임베딩 (JS) |
|
|
589
|
+
| `zod` | ^3.22.0 | 스키마 검증 |
|
|
590
|
+
| `commander` | ^12.0.0 | CLI 파싱 |
|
|
591
|
+
|
|
592
|
+
### 9.2 개발 의존성
|
|
593
|
+
|
|
594
|
+
| 패키지 | 버전 | 용도 |
|
|
595
|
+
|--------|------|------|
|
|
596
|
+
| `typescript` | ^5.4.0 | 타입 시스템 |
|
|
597
|
+
| `vitest` | ^1.4.0 | 테스트 |
|
|
598
|
+
| `tsx` | ^4.7.0 | TS 실행 |
|
|
599
|
+
| `esbuild` | ^0.20.0 | 빌드 |
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
## 10. 향후 확장
|
|
604
|
+
|
|
605
|
+
### Phase 2 (v1.1.0)
|
|
606
|
+
- [ ] 그래프 기반 관계 저장 (Neo4j/Graphiti)
|
|
607
|
+
- [ ] 멀티 프로젝트 학습
|
|
608
|
+
- [ ] 팀 기억 공유 (암호화)
|
|
609
|
+
|
|
610
|
+
### Phase 3 (v2.0.0)
|
|
611
|
+
- [ ] 자동 인사이트 추출 (LLM 기반)
|
|
612
|
+
- [ ] 코드 스니펫 특화 기억
|
|
613
|
+
- [ ] IDE 통합 (VSCode extension)
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
## 11. 성공 지표
|
|
618
|
+
|
|
619
|
+
| 지표 | 측정 방법 | 목표 |
|
|
620
|
+
|------|----------|------|
|
|
621
|
+
| **관련성** | 사용자 피드백 | 80%+ 유용 |
|
|
622
|
+
| **속도** | 응답 지연 | < 500ms |
|
|
623
|
+
| **채택률** | 활성 사용자 | 1000+ |
|
|
624
|
+
| **재사용률** | 기억 활용 빈도 | 50%+ 세션 |
|