a2a-memory 0.11.5 → 0.11.6
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/LICENSE +7 -19
- package/README.md +1 -1
- package/dist/a2a/client.js +1 -252
- package/dist/a2a/discovery.js +1 -115
- package/dist/a2a/index.js +1 -8
- package/dist/a2a/types.js +1 -42
- package/dist/adapters/anthropic.js +1 -117
- package/dist/chunking/chunker.js +1 -163
- package/dist/claude/sync.js +1 -298
- package/dist/cli/commands/add.js +1 -80
- package/dist/cli/commands/claude-sync.js +1 -70
- package/dist/cli/commands/cleanup.js +1 -83
- package/dist/cli/commands/config.js +1 -79
- package/dist/cli/commands/edit.js +1 -69
- package/dist/cli/commands/embed.js +1 -92
- package/dist/cli/commands/extract.js +1 -103
- package/dist/cli/commands/health.js +1 -105
- package/dist/cli/commands/list.js +1 -46
- package/dist/cli/commands/migrate-chunks.js +1 -205
- package/dist/cli/commands/migrate-file-refs.js +1 -183
- package/dist/cli/commands/proficiency.js +1 -146
- package/dist/cli/commands/rm.js +1 -64
- package/dist/cli/commands/search.js +1 -90
- package/dist/cli/commands/setup-wizard.js +1 -387
- package/dist/cli/commands/setup.js +1 -170
- package/dist/cli/commands/skill.js +1 -151
- package/dist/cli/commands/status.js +1 -70
- package/dist/cli/commands/sync.js +1 -202
- package/dist/cli/commands/team.js +1 -142
- package/dist/cli/index.js +1 -87
- package/dist/config/manager.js +1 -372
- package/dist/db/database.js +1 -1400
- package/dist/embedding/e5-provider.js +1 -147
- package/dist/embedding/index.js +1 -34
- package/dist/embedding/local-provider.js +1 -157
- package/dist/embedding/openai-provider.js +1 -92
- package/dist/embedding/quantization.js +1 -89
- package/dist/extraction/dedup-manager.js +1 -161
- package/dist/extraction/emotion-filter.js +1 -33
- package/dist/extraction/extractor.js +1 -648
- package/dist/extraction/file-reference.js +1 -77
- package/dist/extraction/filter.js +1 -86
- package/dist/extraction/scorer.js +1 -142
- package/dist/extraction/similarity.js +1 -85
- package/dist/hooks/client-factory.js +1 -44
- package/dist/hooks/post-tool-use.js +1 -518
- package/dist/hooks/pre-compact.js +1 -209
- package/dist/hooks/session-end.js +1 -633
- package/dist/hooks/session-start.js +1 -549
- package/dist/hooks/shared.js +1 -110
- package/dist/hooks/user-prompt-submit.js +1 -316
- package/dist/i18n/index.js +1 -2
- package/dist/i18n/messages.js +1 -150
- package/dist/index.js +1 -43
- package/dist/lifecycle/cleanup-scheduler.js +1 -137
- package/dist/lifecycle/cleanup.js +1 -116
- package/dist/lifecycle/index.js +1 -13
- package/dist/lifecycle/quality-scorer.js +1 -46
- package/dist/lifecycle/tiering.js +1 -246
- package/dist/llm/client.js +1 -226
- package/dist/llm/index.js +1 -5
- package/dist/proficiency/actr-engine.js +1 -106
- package/dist/proficiency/detection.js +1 -77
- package/dist/proficiency/index.js +1 -9
- package/dist/proficiency/tracker.js +1 -173
- package/dist/proficiency/types.js +1 -8
- package/dist/providers/adapters.js +1 -140
- package/dist/providers/detector.js +1 -57
- package/dist/search/adaptive-router.js +1 -93
- package/dist/search/index.js +1 -9
- package/dist/search/ranker.js +1 -171
- package/dist/search/reranker.js +1 -155
- package/dist/session/parser.js +1 -130
- package/dist/skill/evaluator.js +1 -509
- package/dist/skill/index.js +1 -7
- package/dist/skill/types.js +1 -7
- package/dist/sync/client.js +1 -597
- package/dist/sync/encryption.js +1 -203
- package/dist/sync/index.js +1 -12
- package/dist/sync/queue.js +1 -214
- package/dist/sync/scheduler.js +1 -140
- package/dist/sync/synchronizer.js +1 -241
- package/dist/sync/team-synchronizer.js +1 -204
- package/dist/sync/vector-clock.js +1 -70
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -132
- package/dist/utils/keychain.js +1 -170
- package/dist/utils/logger.js +1 -128
- package/package.json +14 -10
- package/dist/a2a/client.d.ts.map +0 -1
- package/dist/a2a/client.js.map +0 -1
- package/dist/a2a/discovery.d.ts.map +0 -1
- package/dist/a2a/discovery.js.map +0 -1
- package/dist/a2a/index.d.ts.map +0 -1
- package/dist/a2a/index.js.map +0 -1
- package/dist/a2a/types.d.ts.map +0 -1
- package/dist/a2a/types.js.map +0 -1
- package/dist/adapters/anthropic.d.ts.map +0 -1
- package/dist/adapters/anthropic.js.map +0 -1
- package/dist/chunking/chunker.d.ts.map +0 -1
- package/dist/chunking/chunker.js.map +0 -1
- package/dist/claude/sync.d.ts.map +0 -1
- package/dist/claude/sync.js.map +0 -1
- package/dist/cli/commands/add.d.ts.map +0 -1
- package/dist/cli/commands/add.js.map +0 -1
- package/dist/cli/commands/claude-sync.d.ts.map +0 -1
- package/dist/cli/commands/claude-sync.js.map +0 -1
- package/dist/cli/commands/cleanup.d.ts.map +0 -1
- package/dist/cli/commands/cleanup.js.map +0 -1
- package/dist/cli/commands/config.d.ts.map +0 -1
- package/dist/cli/commands/config.js.map +0 -1
- package/dist/cli/commands/edit.d.ts.map +0 -1
- package/dist/cli/commands/edit.js.map +0 -1
- package/dist/cli/commands/embed.d.ts.map +0 -1
- package/dist/cli/commands/embed.js.map +0 -1
- package/dist/cli/commands/extract.d.ts.map +0 -1
- package/dist/cli/commands/extract.js.map +0 -1
- package/dist/cli/commands/health.d.ts.map +0 -1
- package/dist/cli/commands/health.js.map +0 -1
- package/dist/cli/commands/list.d.ts.map +0 -1
- package/dist/cli/commands/list.js.map +0 -1
- package/dist/cli/commands/migrate-chunks.d.ts.map +0 -1
- package/dist/cli/commands/migrate-chunks.js.map +0 -1
- package/dist/cli/commands/migrate-file-refs.d.ts.map +0 -1
- package/dist/cli/commands/migrate-file-refs.js.map +0 -1
- package/dist/cli/commands/proficiency.d.ts.map +0 -1
- package/dist/cli/commands/proficiency.js.map +0 -1
- package/dist/cli/commands/rm.d.ts.map +0 -1
- package/dist/cli/commands/rm.js.map +0 -1
- package/dist/cli/commands/search.d.ts.map +0 -1
- package/dist/cli/commands/search.js.map +0 -1
- package/dist/cli/commands/setup-wizard.d.ts.map +0 -1
- package/dist/cli/commands/setup-wizard.js.map +0 -1
- package/dist/cli/commands/setup.d.ts.map +0 -1
- package/dist/cli/commands/setup.js.map +0 -1
- package/dist/cli/commands/skill.d.ts.map +0 -1
- package/dist/cli/commands/skill.js.map +0 -1
- package/dist/cli/commands/status.d.ts.map +0 -1
- package/dist/cli/commands/status.js.map +0 -1
- package/dist/cli/commands/sync.d.ts.map +0 -1
- package/dist/cli/commands/sync.js.map +0 -1
- package/dist/cli/commands/team.d.ts.map +0 -1
- package/dist/cli/commands/team.js.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/config/manager.d.ts.map +0 -1
- package/dist/config/manager.js.map +0 -1
- package/dist/db/database.d.ts.map +0 -1
- package/dist/db/database.js.map +0 -1
- package/dist/embedding/e5-provider.d.ts.map +0 -1
- package/dist/embedding/e5-provider.js.map +0 -1
- package/dist/embedding/index.d.ts.map +0 -1
- package/dist/embedding/index.js.map +0 -1
- package/dist/embedding/local-provider.d.ts.map +0 -1
- package/dist/embedding/local-provider.js.map +0 -1
- package/dist/embedding/openai-provider.d.ts.map +0 -1
- package/dist/embedding/openai-provider.js.map +0 -1
- package/dist/embedding/quantization.d.ts.map +0 -1
- package/dist/embedding/quantization.js.map +0 -1
- package/dist/extraction/dedup-manager.d.ts.map +0 -1
- package/dist/extraction/dedup-manager.js.map +0 -1
- package/dist/extraction/emotion-filter.d.ts.map +0 -1
- package/dist/extraction/emotion-filter.js.map +0 -1
- package/dist/extraction/extractor.d.ts.map +0 -1
- package/dist/extraction/extractor.js.map +0 -1
- package/dist/extraction/file-reference.d.ts.map +0 -1
- package/dist/extraction/file-reference.js.map +0 -1
- package/dist/extraction/filter.d.ts.map +0 -1
- package/dist/extraction/filter.js.map +0 -1
- package/dist/extraction/scorer.d.ts.map +0 -1
- package/dist/extraction/scorer.js.map +0 -1
- package/dist/extraction/similarity.d.ts.map +0 -1
- package/dist/extraction/similarity.js.map +0 -1
- package/dist/hooks/client-factory.d.ts.map +0 -1
- package/dist/hooks/client-factory.js.map +0 -1
- package/dist/hooks/post-tool-use.d.ts.map +0 -1
- package/dist/hooks/post-tool-use.js.map +0 -1
- package/dist/hooks/pre-compact.d.ts.map +0 -1
- package/dist/hooks/pre-compact.js.map +0 -1
- package/dist/hooks/session-end.d.ts.map +0 -1
- package/dist/hooks/session-end.js.map +0 -1
- package/dist/hooks/session-start.d.ts.map +0 -1
- package/dist/hooks/session-start.js.map +0 -1
- package/dist/hooks/shared.d.ts.map +0 -1
- package/dist/hooks/shared.js.map +0 -1
- package/dist/hooks/user-prompt-submit.d.ts.map +0 -1
- package/dist/hooks/user-prompt-submit.js.map +0 -1
- package/dist/i18n/index.d.ts.map +0 -1
- package/dist/i18n/index.js.map +0 -1
- package/dist/i18n/messages.d.ts.map +0 -1
- package/dist/i18n/messages.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lifecycle/cleanup-scheduler.d.ts.map +0 -1
- package/dist/lifecycle/cleanup-scheduler.js.map +0 -1
- package/dist/lifecycle/cleanup.d.ts.map +0 -1
- package/dist/lifecycle/cleanup.js.map +0 -1
- package/dist/lifecycle/index.d.ts.map +0 -1
- package/dist/lifecycle/index.js.map +0 -1
- package/dist/lifecycle/quality-scorer.d.ts.map +0 -1
- package/dist/lifecycle/quality-scorer.js.map +0 -1
- package/dist/lifecycle/tiering.d.ts.map +0 -1
- package/dist/lifecycle/tiering.js.map +0 -1
- package/dist/llm/client.d.ts.map +0 -1
- package/dist/llm/client.js.map +0 -1
- package/dist/llm/index.d.ts.map +0 -1
- package/dist/llm/index.js.map +0 -1
- package/dist/proficiency/actr-engine.d.ts.map +0 -1
- package/dist/proficiency/actr-engine.js.map +0 -1
- package/dist/proficiency/detection.d.ts.map +0 -1
- package/dist/proficiency/detection.js.map +0 -1
- package/dist/proficiency/index.d.ts.map +0 -1
- package/dist/proficiency/index.js.map +0 -1
- package/dist/proficiency/tracker.d.ts.map +0 -1
- package/dist/proficiency/tracker.js.map +0 -1
- package/dist/proficiency/types.d.ts.map +0 -1
- package/dist/proficiency/types.js.map +0 -1
- package/dist/providers/adapters.d.ts.map +0 -1
- package/dist/providers/adapters.js.map +0 -1
- package/dist/providers/detector.d.ts.map +0 -1
- package/dist/providers/detector.js.map +0 -1
- package/dist/search/adaptive-router.d.ts.map +0 -1
- package/dist/search/adaptive-router.js.map +0 -1
- package/dist/search/index.d.ts.map +0 -1
- package/dist/search/index.js.map +0 -1
- package/dist/search/ranker.d.ts.map +0 -1
- package/dist/search/ranker.js.map +0 -1
- package/dist/search/reranker.d.ts.map +0 -1
- package/dist/search/reranker.js.map +0 -1
- package/dist/session/parser.d.ts.map +0 -1
- package/dist/session/parser.js.map +0 -1
- package/dist/skill/evaluator.d.ts.map +0 -1
- package/dist/skill/evaluator.js.map +0 -1
- package/dist/skill/index.d.ts.map +0 -1
- package/dist/skill/index.js.map +0 -1
- package/dist/skill/types.d.ts.map +0 -1
- package/dist/skill/types.js.map +0 -1
- package/dist/sync/client.d.ts.map +0 -1
- package/dist/sync/client.js.map +0 -1
- package/dist/sync/encryption.d.ts.map +0 -1
- package/dist/sync/encryption.js.map +0 -1
- package/dist/sync/index.d.ts.map +0 -1
- package/dist/sync/index.js.map +0 -1
- package/dist/sync/queue.d.ts.map +0 -1
- package/dist/sync/queue.js.map +0 -1
- package/dist/sync/scheduler.d.ts.map +0 -1
- package/dist/sync/scheduler.js.map +0 -1
- package/dist/sync/synchronizer.d.ts.map +0 -1
- package/dist/sync/synchronizer.js.map +0 -1
- package/dist/sync/team-synchronizer.d.ts.map +0 -1
- package/dist/sync/team-synchronizer.js.map +0 -1
- package/dist/sync/vector-clock.d.ts.map +0 -1
- package/dist/sync/vector-clock.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/utils/keychain.d.ts.map +0 -1
- package/dist/utils/keychain.js.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js.map +0 -1
|
@@ -1,648 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory Extractor
|
|
3
|
-
*
|
|
4
|
-
* 세션 메시지에서 의미 있는 메모리를 추출합니다.
|
|
5
|
-
* 카테고리: error_solution, code_pattern, decision, context, convention
|
|
6
|
-
*/
|
|
7
|
-
import { filterSensitiveInfo } from './filter.js';
|
|
8
|
-
import { deduplicateByContent } from './similarity.js';
|
|
9
|
-
const STRONG_DECISION_KEYWORDS = [
|
|
10
|
-
'chose', 'decided', 'opted for', 'instead of', 'rather than',
|
|
11
|
-
'선택했', '결정했', '대신',
|
|
12
|
-
];
|
|
13
|
-
const WEAK_DECISION_KEYWORDS = [
|
|
14
|
-
'approach', 'strategy', 'decision', '방식', '접근', '전략',
|
|
15
|
-
'선택', '결정',
|
|
16
|
-
];
|
|
17
|
-
const CONVENTION_KEYWORDS = [
|
|
18
|
-
'선호', '항상', '무조건', '습관', '규칙',
|
|
19
|
-
'prefer', 'always', 'never', 'convention', 'rule',
|
|
20
|
-
'style', 'pattern',
|
|
21
|
-
];
|
|
22
|
-
const ERROR_INDICATORS = [
|
|
23
|
-
'error', 'Error', 'ERROR',
|
|
24
|
-
'exception', 'Exception',
|
|
25
|
-
'failed', 'Failed', 'FAILED',
|
|
26
|
-
'traceback', 'Traceback',
|
|
27
|
-
'stack trace',
|
|
28
|
-
'에러', '오류', '실패',
|
|
29
|
-
];
|
|
30
|
-
/**
|
|
31
|
-
* 노이즈 콘텐츠 패턴 — 메모리로 저장하면 안 되는 시스템 메시지
|
|
32
|
-
*/
|
|
33
|
-
const NOISE_PATTERNS = [
|
|
34
|
-
/This session is being continued from a previous conversation/,
|
|
35
|
-
/Base directory for this skill:/,
|
|
36
|
-
/Tool use was interrupted/,
|
|
37
|
-
/<system-reminder>/,
|
|
38
|
-
/pre-push hook/i,
|
|
39
|
-
/A plan file exists from plan mode at:/,
|
|
40
|
-
/Running backend tests/,
|
|
41
|
-
/The following skills? (?:are|were) (?:available|invoked)/,
|
|
42
|
-
/Called the (?:Read|Write|Edit|Glob|Grep|Bash) tool with the following input/,
|
|
43
|
-
/Result of calling the \w+ tool/,
|
|
44
|
-
// Fix 7: Additional noise patterns for low-value tool output memories
|
|
45
|
-
/^Tool: (?:Edit|Read|Write|Glob|Grep|Bash)\b/,
|
|
46
|
-
/^Tool use was rejected/,
|
|
47
|
-
/^File (?:created|updated|written) successfully/,
|
|
48
|
-
/^No files found$/,
|
|
49
|
-
/^The file .+ has been (?:updated|created) successfully/,
|
|
50
|
-
// Sprint 1-1: Additional patterns for tool call logs missed by Fix 7
|
|
51
|
-
/^Tool: (?:Edit|Read|Write|Glob|Grep|Bash|MCP)/i,
|
|
52
|
-
/^(?:Called|Result of calling) the \w+ tool/i,
|
|
53
|
-
/^File (?:created|modified|deleted):/i,
|
|
54
|
-
/^\d+ (?:file|files) (?:found|matched|updated|deleted)/i,
|
|
55
|
-
/^(?:Read|Edit|Write|Glob|Grep|Bash) tool/i,
|
|
56
|
-
/^Searching for /i,
|
|
57
|
-
/^Found \d+ (?:result|results|match|matches)/i,
|
|
58
|
-
// Production fix: File path metadata noise (48% of memories were these patterns)
|
|
59
|
-
/^File: \//,
|
|
60
|
-
/^\{"filePath"/,
|
|
61
|
-
/^\{"file_path"/,
|
|
62
|
-
/\/var\/folders\//,
|
|
63
|
-
/\/tmp\//,
|
|
64
|
-
];
|
|
65
|
-
/**
|
|
66
|
-
* 노이즈 메모리 제목 패턴 — 추출된 메모리 제목이 이 패턴과 일치하면 저장 금지
|
|
67
|
-
* content에서 파생된 제목 또는 content 자체의 첫 줄이 여기에 해당하면 필터링
|
|
68
|
-
*/
|
|
69
|
-
const NOISE_TITLE_PATTERNS = [
|
|
70
|
-
/^Tool: /i,
|
|
71
|
-
/^File (?:created|updated|deleted|modified)/i,
|
|
72
|
-
/^(?:Read|Edit|Write|Glob|Grep|Bash) /i,
|
|
73
|
-
/^Result of /i,
|
|
74
|
-
// Note: [Error] is intentionally excluded — it's a valid error_solution format generated by extractErrorSolutions()
|
|
75
|
-
/^\[(?:Tool|System)\]/i,
|
|
76
|
-
/^(?:Called|Calling) the \w+ tool/i,
|
|
77
|
-
];
|
|
78
|
-
/**
|
|
79
|
-
* 메시지가 노이즈인지 판별
|
|
80
|
-
*/
|
|
81
|
-
export function isNoiseMessage(text) {
|
|
82
|
-
return NOISE_PATTERNS.some((pattern) => pattern.test(text));
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* 세션 메시지에서 메모리 추출
|
|
86
|
-
*/
|
|
87
|
-
export function extractMemories(messages, projectPath) {
|
|
88
|
-
const startTime = Date.now();
|
|
89
|
-
const memories = [];
|
|
90
|
-
let filteredSensitive = 0;
|
|
91
|
-
// 0. 노이즈 메시지 필터링
|
|
92
|
-
const cleanMessages = messages.filter((msg) => {
|
|
93
|
-
const text = getFullText(msg);
|
|
94
|
-
return !isNoiseMessage(text);
|
|
95
|
-
});
|
|
96
|
-
// 1. error_solution 추출
|
|
97
|
-
const errorSolutions = extractErrorSolutions(cleanMessages, projectPath);
|
|
98
|
-
memories.push(...errorSolutions);
|
|
99
|
-
// 2. code_pattern 추출
|
|
100
|
-
const codePatterns = extractCodePatterns(cleanMessages, projectPath);
|
|
101
|
-
memories.push(...codePatterns);
|
|
102
|
-
// 3. decision 추출
|
|
103
|
-
const decisions = extractDecisions(cleanMessages, projectPath);
|
|
104
|
-
memories.push(...decisions);
|
|
105
|
-
// 4. context 추출
|
|
106
|
-
const contexts = extractContexts(cleanMessages, projectPath);
|
|
107
|
-
memories.push(...contexts);
|
|
108
|
-
// 5. convention 추출
|
|
109
|
-
const conventions = extractConventions(cleanMessages, projectPath);
|
|
110
|
-
memories.push(...conventions);
|
|
111
|
-
// 6. learning 추출 (Issue 5 Fix)
|
|
112
|
-
const learnings = extractLearnings(cleanMessages, projectPath);
|
|
113
|
-
memories.push(...learnings);
|
|
114
|
-
// 민감 정보 필터링
|
|
115
|
-
for (let i = 0; i < memories.length; i++) {
|
|
116
|
-
const result = filterSensitiveInfo(memories[i].content);
|
|
117
|
-
if (result.matchCount > 0) {
|
|
118
|
-
memories[i] = { ...memories[i], content: result.filtered };
|
|
119
|
-
filteredSensitive += result.matchCount;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
// Fix 7: Filter out very short content (< 50 chars) — too low value to store
|
|
123
|
-
const meaningful = memories.filter((m) => m.content.length >= 50);
|
|
124
|
-
// Sprint 1-1: Filter by noise title patterns — reject if first line matches tool/file log patterns
|
|
125
|
-
const titleFiltered = meaningful.filter((m) => {
|
|
126
|
-
const firstLine = m.content.split('\n')[0].trim();
|
|
127
|
-
return !NOISE_TITLE_PATTERNS.some((pattern) => pattern.test(firstLine));
|
|
128
|
-
});
|
|
129
|
-
// 중복 제거 (동일 콘텐츠)
|
|
130
|
-
const unique = deduplicateMemories(titleFiltered);
|
|
131
|
-
const sessionInfo = {
|
|
132
|
-
sessionId: cleanMessages[0]?.uuid?.split('-')[0] ?? 'unknown',
|
|
133
|
-
projectPath,
|
|
134
|
-
filePath: '',
|
|
135
|
-
messageCount: cleanMessages.length,
|
|
136
|
-
startTime: cleanMessages[0]?.timestamp,
|
|
137
|
-
endTime: cleanMessages[cleanMessages.length - 1]?.timestamp,
|
|
138
|
-
sizeBytes: 0,
|
|
139
|
-
modifiedAt: Date.now(),
|
|
140
|
-
};
|
|
141
|
-
return {
|
|
142
|
-
memories: unique,
|
|
143
|
-
sessionInfo,
|
|
144
|
-
stats: {
|
|
145
|
-
totalMessages: messages.length,
|
|
146
|
-
extractedPatterns: unique.length,
|
|
147
|
-
filteredSensitive,
|
|
148
|
-
processingTimeMs: Date.now() - startTime,
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* 에러 → 해결 쌍 추출
|
|
154
|
-
*/
|
|
155
|
-
function extractErrorSolutions(messages, projectPath) {
|
|
156
|
-
const results = [];
|
|
157
|
-
for (let i = 0; i < messages.length; i++) {
|
|
158
|
-
const msg = messages[i];
|
|
159
|
-
const text = getFullText(msg);
|
|
160
|
-
// Issue 3 Fix: Check if error indicator is in natural language context
|
|
161
|
-
const hasError = ERROR_INDICATORS.some((ind) => text.includes(ind));
|
|
162
|
-
if (!hasError)
|
|
163
|
-
continue;
|
|
164
|
-
// Skip if message is mostly code (>50% lines are indented or code keywords)
|
|
165
|
-
const lines = text.split('\n');
|
|
166
|
-
const codeLines = lines.filter((line) => {
|
|
167
|
-
const trimmed = line.trim();
|
|
168
|
-
return line.startsWith(' ') || line.startsWith('\t') ||
|
|
169
|
-
trimmed.startsWith('import ') || trimmed.startsWith('function ') ||
|
|
170
|
-
trimmed.startsWith('class ') || trimmed.startsWith('const ') ||
|
|
171
|
-
trimmed.startsWith('let ') || trimmed.startsWith('var ') ||
|
|
172
|
-
trimmed.startsWith('def ') || trimmed.startsWith('if ') ||
|
|
173
|
-
trimmed.startsWith('for ') || trimmed.startsWith('return ');
|
|
174
|
-
}).length;
|
|
175
|
-
if (lines.length > 0 && (codeLines / lines.length) > 0.5)
|
|
176
|
-
continue;
|
|
177
|
-
// Error message should be at least 20 chars (filter single-word matches)
|
|
178
|
-
const errorContext = text.split('\n').find((line) => ERROR_INDICATORS.some((ind) => line.includes(ind)));
|
|
179
|
-
if (!errorContext || errorContext.trim().length < 20)
|
|
180
|
-
continue;
|
|
181
|
-
// 다음 assistant 메시지에서 해결 과정 찾기
|
|
182
|
-
for (let j = i + 1; j < Math.min(i + 5, messages.length); j++) {
|
|
183
|
-
const next = messages[j];
|
|
184
|
-
if (next.type !== 'assistant')
|
|
185
|
-
continue;
|
|
186
|
-
const nextText = getFullText(next);
|
|
187
|
-
const hasToolUse = Array.isArray(next.message.content) &&
|
|
188
|
-
next.message.content.some((b) => b.type === 'tool_use');
|
|
189
|
-
if (hasToolUse || nextText.length > 50) {
|
|
190
|
-
const errorSnippet = text.slice(0, 300);
|
|
191
|
-
const solutionSnippet = nextText.slice(0, 500);
|
|
192
|
-
// Verify solution relevance
|
|
193
|
-
if (!hasToolUse && !verifySolutionRelevance(errorSnippet, solutionSnippet)) {
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
results.push({
|
|
197
|
-
content: `[Error] ${errorSnippet}\n\n[Solution] ${solutionSnippet}`,
|
|
198
|
-
category: 'error_solution',
|
|
199
|
-
tier: 'episodic',
|
|
200
|
-
tags: extractTags(text, 'error'),
|
|
201
|
-
projectPath,
|
|
202
|
-
});
|
|
203
|
-
break;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
return results;
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Error-Solution 페어링 관련성 검증
|
|
211
|
-
*/
|
|
212
|
-
function verifySolutionRelevance(errorText, solutionText) {
|
|
213
|
-
const errorWords = new Set(errorText.toLowerCase().split(/\W+/).filter((w) => w.length > 3));
|
|
214
|
-
const solutionWords = new Set(solutionText.toLowerCase().split(/\W+/).filter((w) => w.length > 3));
|
|
215
|
-
const shared = [...errorWords].filter((w) => solutionWords.has(w));
|
|
216
|
-
// 공유 키워드 2개 이상 필요
|
|
217
|
-
if (shared.length < 2)
|
|
218
|
-
return false;
|
|
219
|
-
// 순수 에러 메시지(스택 트레이스만)면 솔루션 아님
|
|
220
|
-
if (isPureErrorMessage(solutionText))
|
|
221
|
-
return false;
|
|
222
|
-
return true;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* 순수 에러 메시지인지 판별 (솔루션 키워드 없이 스택 트레이스만 포함)
|
|
226
|
-
*/
|
|
227
|
-
function isPureErrorMessage(text) {
|
|
228
|
-
const lines = text.split('\n').filter((l) => l.trim());
|
|
229
|
-
if (lines.length === 0)
|
|
230
|
-
return true;
|
|
231
|
-
// 스택 트레이스 패턴
|
|
232
|
-
const stackTraceLines = lines.filter((l) => /^\s*(at |File |Traceback| File "| raise |>>> )/.test(l));
|
|
233
|
-
// 전체 줄의 70% 이상이 스택 트레이스면 순수 에러
|
|
234
|
-
if (stackTraceLines.length / lines.length > 0.7)
|
|
235
|
-
return true;
|
|
236
|
-
// 솔루션 키워드가 하나라도 있으면 에러가 아님
|
|
237
|
-
const SOLUTION_INDICATORS = [
|
|
238
|
-
'fix', 'solve', 'resolve', 'try', 'use', 'change', 'update', 'install',
|
|
239
|
-
'instead', 'should', 'need to', 'make sure', 'ensure',
|
|
240
|
-
'해결', '수정', '변경', '설치', '시도', '사용',
|
|
241
|
-
];
|
|
242
|
-
const lowerText = text.toLowerCase();
|
|
243
|
-
return !SOLUTION_INDICATORS.some((kw) => lowerText.includes(kw));
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* 반복 사용 도구 패턴 + 파일 수정 패턴 추출
|
|
247
|
-
*/
|
|
248
|
-
function extractCodePatterns(messages, projectPath) {
|
|
249
|
-
const toolCounts = new Map();
|
|
250
|
-
// Issue 1 Fix: Exclude trivial tools from pattern extraction
|
|
251
|
-
const trivialTools = ['Read', 'Glob', 'Grep', 'WebFetch', 'WebSearch'];
|
|
252
|
-
// 파일 수정 패턴 추적
|
|
253
|
-
const fileModifications = new Map(); // 확장자별 수정 횟수
|
|
254
|
-
const dirModifications = new Map(); // 디렉토리별 수정 횟수
|
|
255
|
-
for (const msg of messages) {
|
|
256
|
-
if (!Array.isArray(msg.message.content))
|
|
257
|
-
continue;
|
|
258
|
-
for (const block of msg.message.content) {
|
|
259
|
-
if (block.type !== 'tool_use' || !block.name)
|
|
260
|
-
continue;
|
|
261
|
-
// 파일 수정 패턴 추적 (Write/Edit)
|
|
262
|
-
if ((block.name === 'Write' || block.name === 'Edit') && block.input) {
|
|
263
|
-
const filePath = block.input.file_path;
|
|
264
|
-
if (filePath) {
|
|
265
|
-
const lastDot = filePath.lastIndexOf('.');
|
|
266
|
-
const ext = lastDot >= 0 ? filePath.slice(lastDot) : '';
|
|
267
|
-
const parts = filePath.split('/');
|
|
268
|
-
const dir = parts.slice(-3, -1).join('/');
|
|
269
|
-
if (ext)
|
|
270
|
-
fileModifications.set(ext, (fileModifications.get(ext) || 0) + 1);
|
|
271
|
-
if (dir)
|
|
272
|
-
dirModifications.set(dir, (dirModifications.get(dir) || 0) + 1);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
// Skip trivial tools
|
|
276
|
-
if (trivialTools.includes(block.name))
|
|
277
|
-
continue;
|
|
278
|
-
const entry = toolCounts.get(block.name) ?? { count: 0, samples: [] };
|
|
279
|
-
entry.count++;
|
|
280
|
-
if (entry.samples.length < 3 && block.input) {
|
|
281
|
-
// 키워드 기반 샘플링: 의미있는 부분 우선 추출
|
|
282
|
-
const inputStr = JSON.stringify(block.input);
|
|
283
|
-
if (inputStr.length <= 200) {
|
|
284
|
-
entry.samples.push(inputStr);
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
const keywords = ['error', 'fix', 'solution', 'pattern', 'config', 'import', 'export', 'function', 'class'];
|
|
288
|
-
const lowerInput = inputStr.toLowerCase();
|
|
289
|
-
let bestStart = 0;
|
|
290
|
-
for (const kw of keywords) {
|
|
291
|
-
const idx = lowerInput.indexOf(kw);
|
|
292
|
-
if (idx >= 0) {
|
|
293
|
-
bestStart = Math.max(0, idx - 50);
|
|
294
|
-
break;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
entry.samples.push(inputStr.slice(bestStart, bestStart + 200));
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
toolCounts.set(block.name, entry);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
const results = [];
|
|
304
|
-
// 기존: 도구 사용 빈도 패턴
|
|
305
|
-
for (const [toolName, data] of toolCounts) {
|
|
306
|
-
// Issue 1 Fix: Increase threshold from 3 to 5
|
|
307
|
-
if (data.count < 5)
|
|
308
|
-
continue;
|
|
309
|
-
results.push({
|
|
310
|
-
content: `Tool "${toolName}" used ${data.count} times. Samples:\n${data.samples.join('\n')}`,
|
|
311
|
-
category: 'code_pattern',
|
|
312
|
-
tier: 'semantic',
|
|
313
|
-
tags: [toolName, 'pattern', 'tool-usage'],
|
|
314
|
-
projectPath,
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
// 신규: 파일 수정 패턴 (3개 이상 수정된 확장자)
|
|
318
|
-
if (fileModifications.size > 0) {
|
|
319
|
-
const topExtensions = [...fileModifications.entries()]
|
|
320
|
-
.filter(([, count]) => count >= 3)
|
|
321
|
-
.sort((a, b) => b[1] - a[1])
|
|
322
|
-
.slice(0, 5);
|
|
323
|
-
if (topExtensions.length > 0) {
|
|
324
|
-
const topDirs = [...dirModifications.entries()]
|
|
325
|
-
.sort((a, b) => b[1] - a[1])
|
|
326
|
-
.slice(0, 3);
|
|
327
|
-
results.push({
|
|
328
|
-
content: `Code modification pattern: ${topExtensions.map(([ext, n]) => `${ext}(${n})`).join(', ')}. ` +
|
|
329
|
-
`Directories: ${topDirs.map(([dir, n]) => `${dir}(${n})`).join(', ')}`,
|
|
330
|
-
category: 'code_pattern',
|
|
331
|
-
tier: 'semantic',
|
|
332
|
-
tags: ['code-pattern', 'file-modification', ...topExtensions.map(([ext]) => ext.replace('.', ''))],
|
|
333
|
-
projectPath,
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
return results;
|
|
338
|
-
}
|
|
339
|
-
/**
|
|
340
|
-
* 의사 결정 메시지 추출
|
|
341
|
-
*/
|
|
342
|
-
function extractDecisions(messages, projectPath) {
|
|
343
|
-
const results = [];
|
|
344
|
-
for (const msg of messages) {
|
|
345
|
-
const text = getFullText(msg);
|
|
346
|
-
if (text.length < 50)
|
|
347
|
-
continue; // minimum 50 chars for meaningful decisions
|
|
348
|
-
// Issue 2 Fix: Skip git diffs, changelogs, version patterns
|
|
349
|
-
if (text.startsWith('diff --git') ||
|
|
350
|
-
text.includes('CHANGELOG') ||
|
|
351
|
-
/v\d+\.\d+\.\d+/.test(text)) {
|
|
352
|
-
continue;
|
|
353
|
-
}
|
|
354
|
-
// Remove code blocks and check remaining text for keyword matching
|
|
355
|
-
const textWithoutCode = text.replace(/```[\s\S]*?```/g, '').trim();
|
|
356
|
-
if (!textWithoutCode)
|
|
357
|
-
continue;
|
|
358
|
-
const lowerText = textWithoutCode.toLowerCase();
|
|
359
|
-
// Strong keyword 1개 이상 OR Weak keyword 2개 이상
|
|
360
|
-
const strongCount = STRONG_DECISION_KEYWORDS.filter((kw) => lowerText.includes(kw.toLowerCase())).length;
|
|
361
|
-
const weakCount = WEAK_DECISION_KEYWORDS.filter((kw) => lowerText.includes(kw.toLowerCase())).length;
|
|
362
|
-
if (strongCount < 1 && weakCount < 2)
|
|
363
|
-
continue;
|
|
364
|
-
results.push({
|
|
365
|
-
content: textWithoutCode.slice(0, 800),
|
|
366
|
-
category: 'decision',
|
|
367
|
-
tier: 'semantic',
|
|
368
|
-
tags: extractTags(textWithoutCode, 'decision'),
|
|
369
|
-
projectPath,
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
return results;
|
|
373
|
-
}
|
|
374
|
-
const CONTEXT_KEYWORDS = [
|
|
375
|
-
'setup', 'install', 'configure', 'environment', 'initialization',
|
|
376
|
-
'설정', '설치', '환경설정', '초기화',
|
|
377
|
-
];
|
|
378
|
-
const LEARNING_KEYWORDS = [
|
|
379
|
-
'learned', 'TIL', 'realized', 'understood', 'figured out', 'discovery', 'insight',
|
|
380
|
-
'배웠', '깨달', '발견', '알게 됐', '이해했',
|
|
381
|
-
];
|
|
382
|
-
/**
|
|
383
|
-
* 프로젝트 컨텍스트 추출 (첫 human/system 메시지)
|
|
384
|
-
*/
|
|
385
|
-
function extractContexts(messages, projectPath) {
|
|
386
|
-
const results = [];
|
|
387
|
-
for (const msg of messages) {
|
|
388
|
-
if (msg.type !== 'human' && msg.type !== 'system')
|
|
389
|
-
continue;
|
|
390
|
-
// Filter system prompts and CLAUDE.md injections
|
|
391
|
-
if (msg.message.role === 'system')
|
|
392
|
-
continue;
|
|
393
|
-
const text = getFullText(msg);
|
|
394
|
-
if (text.length < 50)
|
|
395
|
-
continue;
|
|
396
|
-
// Filter system-reminder blocks and large CLAUDE.md content
|
|
397
|
-
if (text.includes('<system-reminder>'))
|
|
398
|
-
continue;
|
|
399
|
-
if (text.includes('CLAUDE.md') && text.length > 500)
|
|
400
|
-
continue;
|
|
401
|
-
const lowerText = text.toLowerCase();
|
|
402
|
-
const matchedKeywords = CONTEXT_KEYWORDS.filter((kw) => lowerText.includes(kw.toLowerCase()));
|
|
403
|
-
const msgIndex = messages.indexOf(msg);
|
|
404
|
-
// 조건 강화: (1) 첫 3개 메시지, 또는 (2) context 키워드 2개 이상 동시 포함
|
|
405
|
-
if (msgIndex < 3 || matchedKeywords.length >= 2) {
|
|
406
|
-
results.push({
|
|
407
|
-
content: text.slice(0, 1000),
|
|
408
|
-
category: 'context',
|
|
409
|
-
tier: 'semantic',
|
|
410
|
-
tags: extractTags(text, 'context'),
|
|
411
|
-
projectPath,
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
return results;
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* 사용자 규칙/컨벤션 추출
|
|
419
|
-
*/
|
|
420
|
-
function extractConventions(messages, projectPath) {
|
|
421
|
-
const results = [];
|
|
422
|
-
for (const msg of messages) {
|
|
423
|
-
if (msg.type !== 'human' && msg.type !== 'assistant')
|
|
424
|
-
continue;
|
|
425
|
-
const text = getFullText(msg);
|
|
426
|
-
if (text.length < 20)
|
|
427
|
-
continue;
|
|
428
|
-
// assistant 메시지일 경우 규칙 제안 패턴 필수
|
|
429
|
-
if (msg.type === 'assistant') {
|
|
430
|
-
const hasRuleProposal = /(?:should|must|always|never|recommend|규칙|원칙|필수|금지)/i.test(text);
|
|
431
|
-
if (!hasRuleProposal)
|
|
432
|
-
continue;
|
|
433
|
-
}
|
|
434
|
-
const hasKeyword = CONVENTION_KEYWORDS.some((kw) => text.toLowerCase().includes(kw.toLowerCase()));
|
|
435
|
-
if (!hasKeyword)
|
|
436
|
-
continue;
|
|
437
|
-
results.push({
|
|
438
|
-
content: text.slice(0, 500),
|
|
439
|
-
category: 'convention',
|
|
440
|
-
tier: 'semantic',
|
|
441
|
-
tags: extractTags(text, 'convention'),
|
|
442
|
-
projectPath,
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
return results;
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* Issue 5 Fix: Learning/insight 추출
|
|
449
|
-
*/
|
|
450
|
-
function extractLearnings(messages, projectPath) {
|
|
451
|
-
const results = [];
|
|
452
|
-
for (const msg of messages) {
|
|
453
|
-
// Both human and assistant can express learnings
|
|
454
|
-
if (msg.type !== 'human' && msg.type !== 'assistant')
|
|
455
|
-
continue;
|
|
456
|
-
const text = getFullText(msg);
|
|
457
|
-
if (text.length < 30)
|
|
458
|
-
continue;
|
|
459
|
-
const hasKeyword = LEARNING_KEYWORDS.some((kw) => text.toLowerCase().includes(kw.toLowerCase()));
|
|
460
|
-
if (!hasKeyword)
|
|
461
|
-
continue;
|
|
462
|
-
results.push({
|
|
463
|
-
content: text.slice(0, 800),
|
|
464
|
-
category: 'learning',
|
|
465
|
-
tier: 'episodic', // Fresh learnings start as episodic
|
|
466
|
-
tags: extractTags(text, 'learning'),
|
|
467
|
-
projectPath,
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
return results;
|
|
471
|
-
}
|
|
472
|
-
/**
|
|
473
|
-
* 메시지에서 전체 텍스트 추출
|
|
474
|
-
*/
|
|
475
|
-
function getFullText(message) {
|
|
476
|
-
if (typeof message.message.content === 'string') {
|
|
477
|
-
return message.message.content;
|
|
478
|
-
}
|
|
479
|
-
return message.message.content
|
|
480
|
-
.map((block) => {
|
|
481
|
-
if (block.type === 'text' && block.text)
|
|
482
|
-
return block.text;
|
|
483
|
-
if (block.type === 'tool_result' && block.content)
|
|
484
|
-
return block.content;
|
|
485
|
-
return '';
|
|
486
|
-
})
|
|
487
|
-
.filter(Boolean)
|
|
488
|
-
.join('\n');
|
|
489
|
-
}
|
|
490
|
-
const TECH_NAMES = [
|
|
491
|
-
'react', 'vue', 'angular', 'typescript', 'javascript', 'python', 'java',
|
|
492
|
-
'postgresql', 'mysql', 'redis', 'docker', 'kubernetes', 'aws', 'gcp',
|
|
493
|
-
'fastapi', 'express', 'next.js', 'node.js', 'git', 'graphql', 'rest',
|
|
494
|
-
'webpack', 'vite', 'eslint', 'vitest', 'jest', 'playwright', 'sqlite',
|
|
495
|
-
];
|
|
496
|
-
const WORK_TYPES = [
|
|
497
|
-
'deploy', 'debug', 'refactor', 'test', 'review', 'optimize', 'migrate',
|
|
498
|
-
'setup', 'config', 'build', 'release', 'fix', 'implement', 'upgrade',
|
|
499
|
-
];
|
|
500
|
-
// P3-1: 모듈 레벨 Set 상수 — 함수 호출마다 배열 재생성 방지
|
|
501
|
-
const LOW_VALUE_EXTS = new Set(['md', 'txt', 'json', 'yml', 'yaml', 'xml', 'html', 'css']);
|
|
502
|
-
const MEANINGFUL_EXTS = new Set(['py', 'ts', 'tsx', 'js', 'jsx', 'java', 'go', 'rs', 'rb', 'swift', 'kt']);
|
|
503
|
-
/**
|
|
504
|
-
* 텍스트에서 자동 태그 추출
|
|
505
|
-
*/
|
|
506
|
-
function extractTags(text, category) {
|
|
507
|
-
const tags = [category];
|
|
508
|
-
// 파일 경로 추출 (최대 200자로 제한하여 catastrophic backtracking 방지)
|
|
509
|
-
const fileMatch = text.match(/[\w/.-]{1,200}\.\w{1,10}/g);
|
|
510
|
-
if (fileMatch) {
|
|
511
|
-
const extensions = new Set(fileMatch
|
|
512
|
-
.map((f) => f.split('.').pop())
|
|
513
|
-
.filter((ext) => ext.length <= 5 && ext.length > 1)
|
|
514
|
-
.filter((ext) => !/^\d+$/.test(ext))
|
|
515
|
-
.filter((ext) => !LOW_VALUE_EXTS.has(ext.toLowerCase()))
|
|
516
|
-
.filter((ext) => MEANINGFUL_EXTS.has(ext.toLowerCase())));
|
|
517
|
-
tags.push(...[...extensions].slice(0, 2));
|
|
518
|
-
}
|
|
519
|
-
const lowerText = text.toLowerCase();
|
|
520
|
-
// 기술명 자동 감지
|
|
521
|
-
for (const tech of TECH_NAMES) {
|
|
522
|
-
if (lowerText.includes(tech)) {
|
|
523
|
-
tags.push(tech);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
// 작업 유형 자동 감지
|
|
527
|
-
for (const work of WORK_TYPES) {
|
|
528
|
-
if (lowerText.includes(work)) {
|
|
529
|
-
tags.push(work);
|
|
530
|
-
break; // 작업 유형은 1개만
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
// 태그 유효성 필터 + 최대 5개 (중복 제거 후)
|
|
534
|
-
return [...new Set(tags)]
|
|
535
|
-
.filter((t) => t.length >= 2 && !/^\d+$/.test(t))
|
|
536
|
-
.map((t) => t.toLowerCase())
|
|
537
|
-
.slice(0, 5);
|
|
538
|
-
}
|
|
539
|
-
/**
|
|
540
|
-
* 중복 메모리 제거 (콘텐츠 유사도 기반)
|
|
541
|
-
*/
|
|
542
|
-
function deduplicateMemories(memories) {
|
|
543
|
-
return deduplicateByContent(memories, 0.7);
|
|
544
|
-
}
|
|
545
|
-
// ============================================================
|
|
546
|
-
// LLM-enhanced extraction (async)
|
|
547
|
-
// ============================================================
|
|
548
|
-
const CLASSIFIABLE_CATEGORIES = [
|
|
549
|
-
'error_solution', 'code_pattern', 'decision', 'convention', 'project_knowledge', 'learning',
|
|
550
|
-
];
|
|
551
|
-
/**
|
|
552
|
-
* LLM 기반 보완 추출 — 패턴 매칭이 부족할 때 LLM으로 추가 메모리 추출
|
|
553
|
-
*/
|
|
554
|
-
async function _llmExtractSupplemental(messages, llmClient, projectPath) {
|
|
555
|
-
// 마지막 20개 메시지 텍스트 수집
|
|
556
|
-
const recentMessages = messages.slice(-20);
|
|
557
|
-
const conversationText = recentMessages
|
|
558
|
-
.map((m) => {
|
|
559
|
-
const role = m.type === 'human' ? 'User' : 'Assistant';
|
|
560
|
-
const text = getFullText(m).slice(0, 500);
|
|
561
|
-
return `[${role}]: ${text}`;
|
|
562
|
-
})
|
|
563
|
-
.filter((t) => t.length > 10)
|
|
564
|
-
.join('\n\n')
|
|
565
|
-
.slice(0, 6000);
|
|
566
|
-
if (!conversationText)
|
|
567
|
-
return [];
|
|
568
|
-
const exampleJson = '[{"category": "...", "content": "...", "tags": ["..."]}]';
|
|
569
|
-
const prompt = `다음 개발 대화에서 나중에 유용할 핵심 지식을 3~5개 추출하세요.\n각각 category(error_solution/code_pattern/decision/project_knowledge/convention), content, tags를 JSON 배열로 반환.\n\n대화:\n${conversationText}\n\nJSON 배열만 반환 (마크다운 코드 블록 없이):\n${exampleJson}`;
|
|
570
|
-
try {
|
|
571
|
-
const response = await llmClient.complete(prompt);
|
|
572
|
-
const cleaned = response.replace(/```(?:json)?\s*\n?([\s\S]*?)\n?```/g, '$1').trim();
|
|
573
|
-
const parsed = JSON.parse(cleaned);
|
|
574
|
-
if (!Array.isArray(parsed))
|
|
575
|
-
return [];
|
|
576
|
-
return parsed
|
|
577
|
-
.filter((item) => item.content &&
|
|
578
|
-
item.content.length >= 50 &&
|
|
579
|
-
CLASSIFIABLE_CATEGORIES.includes(item.category))
|
|
580
|
-
.map((item) => ({
|
|
581
|
-
content: item.content.slice(0, 800),
|
|
582
|
-
category: item.category,
|
|
583
|
-
tier: 'semantic',
|
|
584
|
-
tags: Array.isArray(item.tags) ? item.tags.slice(0, 5) : ['llm-extracted'],
|
|
585
|
-
projectPath,
|
|
586
|
-
}));
|
|
587
|
-
}
|
|
588
|
-
catch {
|
|
589
|
-
// JSON 파싱 실패 시 빈 배열 반환 (graceful)
|
|
590
|
-
return [];
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
/**
|
|
594
|
-
* LLM 기반 분류가 포함된 메모리 추출 (async)
|
|
595
|
-
* LLM 없으면 extractMemories와 동일한 결과
|
|
596
|
-
*/
|
|
597
|
-
export async function extractMemoriesWithLLM(messages, projectPath, llmClient) {
|
|
598
|
-
const result = extractMemories(messages, projectPath);
|
|
599
|
-
if (!llmClient)
|
|
600
|
-
return result;
|
|
601
|
-
// LLM 보완 추출 (패턴 매칭 결과가 3개 이하이고 메시지가 충분할 때)
|
|
602
|
-
if (result.memories.length <= 3 && messages.length >= 10) {
|
|
603
|
-
try {
|
|
604
|
-
const supplemental = await _llmExtractSupplemental(messages, llmClient, projectPath);
|
|
605
|
-
result.memories.push(...supplemental);
|
|
606
|
-
}
|
|
607
|
-
catch {
|
|
608
|
-
// 보완 추출 실패는 무시
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
// 낮은 신뢰도 카테고리 메모리들에 대해 LLM 재분류 시도
|
|
612
|
-
const RECLASSIFIABLE = ['context', 'decision', 'convention'];
|
|
613
|
-
for (let i = 0; i < result.memories.length; i++) {
|
|
614
|
-
if (!RECLASSIFIABLE.includes(result.memories[i].category))
|
|
615
|
-
continue;
|
|
616
|
-
try {
|
|
617
|
-
const classified = await llmClient.classify(result.memories[i].content, CLASSIFIABLE_CATEGORIES);
|
|
618
|
-
if (CLASSIFIABLE_CATEGORIES.includes(classified)) {
|
|
619
|
-
result.memories[i] = { ...result.memories[i], category: classified };
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
catch {
|
|
623
|
-
// LLM 실패 시 기존 카테고리 유지
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
return result;
|
|
627
|
-
}
|
|
628
|
-
/**
|
|
629
|
-
* LLM 기반 세션 요약 생성
|
|
630
|
-
*/
|
|
631
|
-
export async function summarizeSession(messages, llmClient) {
|
|
632
|
-
const contents = messages
|
|
633
|
-
.filter((m) => m.type === 'assistant')
|
|
634
|
-
.map((m) => {
|
|
635
|
-
if (typeof m.message.content === 'string')
|
|
636
|
-
return m.message.content;
|
|
637
|
-
return m.message.content
|
|
638
|
-
.filter((b) => b.type === 'text' && b.text)
|
|
639
|
-
.map((b) => b.text)
|
|
640
|
-
.join('\n');
|
|
641
|
-
})
|
|
642
|
-
.filter((t) => t.length > 20)
|
|
643
|
-
.slice(0, 10);
|
|
644
|
-
if (contents.length === 0)
|
|
645
|
-
return '';
|
|
646
|
-
return llmClient.summarize(contents);
|
|
647
|
-
}
|
|
648
|
-
//# sourceMappingURL=extractor.js.map
|
|
1
|
+
(function(_0x63b572,_0x30a3d7){function _0x50a65c(_0x3171fb,_0x1737e4){return _0x4115(_0x3171fb- -0x2cd,_0x1737e4);}const _0x48435f=_0x63b572();function _0x2970f1(_0x23b1b3,_0x3fab69){return _0x4115(_0x3fab69- -0x19b,_0x23b1b3);}while(!![]){try{const _0x4baf56=-parseInt(_0x2970f1(-0x24,-0x67))/0x1*(parseInt(_0x2970f1(-0xb6,-0x32))/0x2)+parseInt(_0x50a65c(-0x10f,-0x159))/0x3+parseInt(_0x50a65c(-0xe6,-0x133))/0x4*(-parseInt(_0x50a65c(-0x18b,-0x133))/0x5)+parseInt(_0x50a65c(-0x10e,-0x17c))/0x6+parseInt(_0x50a65c(-0x128,-0x173))/0x7*(parseInt(_0x50a65c(-0x12b,-0x9d))/0x8)+-parseInt(_0x2970f1(-0x1,0x5f))/0x9*(-parseInt(_0x2970f1(-0xa,-0x6a))/0xa)+parseInt(_0x2970f1(0x2c,-0x7))/0xb*(-parseInt(_0x50a65c(-0x100,-0x185))/0xc);if(_0x4baf56===_0x30a3d7)break;else _0x48435f['push'](_0x48435f['shift']());}catch(_0xd5569a){_0x48435f['push'](_0x48435f['shift']());}}}(_0x1ef3,0x43903));import{filterSensitiveInfo}from'./filter.js';function _0x5e897f(_0x4826f1,_0x41a512){return _0x4115(_0x4826f1- -0xed,_0x41a512);}import{deduplicateByContent}from'./similarity.js';const STRONG_DECISION_KEYWORDS=[_0x2d741e(0xa4,0x36),_0x2d741e(-0xa0,-0x68),_0x2d741e(0x88,0x85),_0x5e897f(0x11a,0xc1),_0x5e897f(0xf8,0x81)+'n',_0x5e897f(0x6e,0x40),_0x5e897f(0x11e,0x126),'대신'],WEAK_DECISION_KEYWORDS=[_0x2d741e(0xc,-0x41),_0x5e897f(0x20,0x6d),_0x2d741e(-0x57,0xd),'방식','접근','전략','선택','결정'],CONVENTION_KEYWORDS=['선호','항상',_0x5e897f(0xdb,0xef),'습관','규칙',_0x5e897f(0x4e,0x9b),'always',_0x2d741e(0x11d,0x99),_0x5e897f(0x8b,0x113),_0x5e897f(0xb0,0x138),'style','pattern'],ERROR_INDICATORS=[_0x5e897f(0xbe,0xba),_0x5e897f(0x3a,0x4c),_0x2d741e(-0x35,-0x43),_0x5e897f(0xaf,0x66),_0x2d741e(-0x64,-0x1c),_0x2d741e(0x44,0x9e),_0x5e897f(0xb1,0x7a),'FAILED',_0x5e897f(0x3f,-0x4b),_0x5e897f(0x99,0xb),'stack\x20trac'+'e','에러','오류','실패'];function _0x2d741e(_0x5d1deb,_0x493c4d){return _0x4115(_0x493c4d- -0x171,_0x5d1deb);}function _0x4115(_0x53c079,_0x3277e9){_0x53c079=_0x53c079-0x103;const _0x1ef3f2=_0x1ef3();let _0x41154b=_0x1ef3f2[_0x53c079];if(_0x4115['ZtUNVu']===undefined){var _0x39545a=function(_0x16883e){const _0x396e01='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4eba48='',_0x1e5963='';for(let _0x5367fd=0x0,_0x8f6fc5,_0x3fd13b,_0x158809=0x0;_0x3fd13b=_0x16883e['charAt'](_0x158809++);~_0x3fd13b&&(_0x8f6fc5=_0x5367fd%0x4?_0x8f6fc5*0x40+_0x3fd13b:_0x3fd13b,_0x5367fd++%0x4)?_0x4eba48+=String['fromCharCode'](0xff&_0x8f6fc5>>(-0x2*_0x5367fd&0x6)):0x0){_0x3fd13b=_0x396e01['indexOf'](_0x3fd13b);}for(let _0x30918e=0x0,_0x442efa=_0x4eba48['length'];_0x30918e<_0x442efa;_0x30918e++){_0x1e5963+='%'+('00'+_0x4eba48['charCodeAt'](_0x30918e)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x1e5963);};_0x4115['vOgnkt']=_0x39545a,_0x4115['QWpITN']={},_0x4115['ZtUNVu']=!![];}const _0x41b82d=_0x1ef3f2[0x0],_0xab1c2d=_0x53c079+_0x41b82d,_0x1050cb=_0x4115['QWpITN'][_0xab1c2d];return!_0x1050cb?(_0x41154b=_0x4115['vOgnkt'](_0x41154b),_0x4115['QWpITN'][_0xab1c2d]=_0x41154b):_0x41154b=_0x1050cb,_0x41154b;}const NOISE_PATTERNS=[/This session is being continued from a previous conversation/,/Base directory for this skill:/,/Tool use was interrupted/,/<system-reminder>/,/pre-push hook/i,/A plan file exists from plan mode at:/,/Running backend tests/,/The following skills? (?:are|were) (?:available|invoked)/,/Called the (?:Read|Write|Edit|Glob|Grep|Bash) tool with the following input/,/Result of calling the \w+ tool/,/^Tool: (?:Edit|Read|Write|Glob|Grep|Bash)\b/,/^Tool use was rejected/,/^File (?:created|updated|written) successfully/,/^No files found$/,/^The file .+ has been (?:updated|created) successfully/,/^Tool: (?:Edit|Read|Write|Glob|Grep|Bash|MCP)/i,/^(?:Called|Result of calling) the \w+ tool/i,/^File (?:created|modified|deleted):/i,/^\d+ (?:file|files) (?:found|matched|updated|deleted)/i,/^(?:Read|Edit|Write|Glob|Grep|Bash) tool/i,/^Searching for /i,/^Found \d+ (?:result|results|match|matches)/i,/^File: \//,/^\{"filePath"/,/^\{"file_path"/,/\/var\/folders\//,/\/tmp\//],NOISE_TITLE_PATTERNS=[/^Tool: /i,/^File (?:created|updated|deleted|modified)/i,/^(?:Read|Edit|Write|Glob|Grep|Bash) /i,/^Result of /i,/^\[(?:Tool|System)\]/i,/^(?:Called|Calling) the \w+ tool/i];export function isNoiseMessage(_0x331681){function _0x37a7c2(_0x123eb5,_0x4a3838){return _0x2d741e(_0x4a3838,_0x123eb5-0x39);}return NOISE_PATTERNS['some'](_0x351324=>_0x351324[_0x37a7c2(0x2,-0x6d)](_0x331681));}export function extractMemories(_0x57eab8,_0x43a7fb){const _0x488b04={'hJKnL':function(_0x5476fe,_0x1bdc14,_0x2b721e){return _0x5476fe(_0x1bdc14,_0x2b721e);},'AUyLc':function(_0x2eff40,_0x163ba5){return _0x2eff40===_0x163ba5;},'xZofg':function(_0x9ffb85,_0x23cdb9,_0x2f18e2){return _0x9ffb85(_0x23cdb9,_0x2f18e2);},'uvzCR':function(_0x484417,_0xabab80,_0x1454b5){return _0x484417(_0xabab80,_0x1454b5);},'rhTZm':function(_0x450189,_0x56f115,_0x1a5fbf){return _0x450189(_0x56f115,_0x1a5fbf);},'ROZJr':function(_0xcc6e8b,_0x27c70){return _0xcc6e8b(_0x27c70);},'mVUaP':function(_0x211921,_0x392787){return _0x211921>_0x392787;},'HsEaP':function(_0x2ddfe3,_0x507054){return _0x2ddfe3(_0x507054);},'TophA':_0x213f39(0x502,0x46f),'uIQoR':function(_0x479356,_0x499d4e){return _0x479356-_0x499d4e;}},_0xb5ac95=Date[_0x213f39(0x5dd,0x5e8)](),_0x479b74=[];let _0x381694=0x0;const _0x524622=_0x57eab8[_0x1ebdc5(0x3b6,0x340)](_0xdfc963=>{const _0x105aa9=getFullText(_0xdfc963);return!isNoiseMessage(_0x105aa9);}),_0x377cfc=extractErrorSolutions(_0x524622,_0x43a7fb);_0x479b74[_0x1ebdc5(0x312,0x2a8)](..._0x377cfc);const _0x196c42=_0x488b04['xZofg'](extractCodePatterns,_0x524622,_0x43a7fb);function _0x1ebdc5(_0x274bbc,_0x4e0ced){return _0x2d741e(_0x274bbc,_0x4e0ced-0x2cd);}_0x479b74[_0x1ebdc5(0x232,0x2a8)](..._0x196c42);const _0x581133=_0x488b04['uvzCR'](extractDecisions,_0x524622,_0x43a7fb);_0x479b74[_0x1ebdc5(0x21b,0x2a8)](..._0x581133);const _0x55546b=_0x488b04[_0x1ebdc5(0x1dc,0x263)](extractContexts,_0x524622,_0x43a7fb);_0x479b74[_0x1ebdc5(0x261,0x2a8)](..._0x55546b);const _0x24c15b=extractConventions(_0x524622,_0x43a7fb);_0x479b74[_0x213f39(0x510,0x55f)](..._0x24c15b);const _0x50722e=extractLearnings(_0x524622,_0x43a7fb);_0x479b74['push'](..._0x50722e);for(let _0x274cd8=0x0;_0x274cd8<_0x479b74[_0x213f39(0x5d9,0x61c)];_0x274cd8++){const _0x7575f3=_0x488b04[_0x213f39(0x5ec,0x5ac)](filterSensitiveInfo,_0x479b74[_0x274cd8][_0x213f39(0x51b,0x576)]);_0x488b04[_0x1ebdc5(0x2d6,0x289)](_0x7575f3['matchCount'],0x0)&&(_0x479b74[_0x274cd8]={..._0x479b74[_0x274cd8],'content':_0x7575f3['filtered']},_0x381694+=_0x7575f3['matchCount']);}const _0x5458b7=_0x479b74[_0x213f39(0x5a8,0x550)](_0x48b85e=>_0x48b85e['content'][_0x1ebdc5(0x3f6,0x371)]>=0x32);function _0x213f39(_0xe1b585,_0x2c9a75){return _0x2d741e(_0x2c9a75,_0xe1b585-0x535);}const _0x28a288=_0x5458b7[_0x1ebdc5(0x3c8,0x340)](_0x1ce42f=>{function _0x467abf(_0x37e200,_0x423ac9){return _0x1ebdc5(_0x423ac9,_0x37e200-0x1ad);}function _0x225fae(_0x4abc06,_0x128629){return _0x1ebdc5(_0x128629,_0x4abc06- -0x45f);}const _0x3e288f={'OdxIP':function(_0x2f6733,_0x202d66,_0x4bafd4){return _0x488b04['hJKnL'](_0x2f6733,_0x202d66,_0x4bafd4);}};if(_0x488b04[_0x467abf(0x501,0x57e)](_0x225fae(-0xde,-0xa4),_0x467abf(0x488,0x3f5)))_0x4efe0b['push']({'content':_0x126b51[_0x467abf(0x420,0x4ab)](0x0,0x3e8),'category':_0x467abf(0x4e0,0x55e),'tier':'semantic','tags':_0x3e288f[_0x225fae(-0x1f8,-0x1d3)](_0x5b420d,_0x13f117,'context'),'projectPath':_0x29f370});else{const _0x409ec4=_0x1ce42f[_0x467abf(0x460,0x3ef)][_0x467abf(0x4e4,0x4c5)]('\x0a')[0x0][_0x225fae(-0x175,-0x12a)]();return!NOISE_TITLE_PATTERNS[_0x225fae(-0x15d,-0x111)](_0x50e267=>_0x50e267[_0x467abf(0x443,0x46c)](_0x409ec4));}}),_0x4b2fa7=_0x488b04['HsEaP'](deduplicateMemories,_0x28a288),_0x4d0cc8={'sessionId':_0x524622[0x0]?.[_0x213f39(0x549,0x571)]?.[_0x1ebdc5(0x2b5,0x337)]('-')[0x0]??_0x488b04[_0x213f39(0x5bd,0x5fc)],'projectPath':_0x43a7fb,'filePath':'','messageCount':_0x524622[_0x213f39(0x5d9,0x5fd)],'startTime':_0x524622[0x0]?.[_0x213f39(0x55d,0x584)],'endTime':_0x524622[_0x488b04['uIQoR'](_0x524622[_0x213f39(0x5d9,0x647)],0x1)]?.[_0x213f39(0x55d,0x5ed)],'sizeBytes':0x0,'modifiedAt':Date[_0x1ebdc5(0x382,0x375)]()};return{'memories':_0x4b2fa7,'sessionInfo':_0x4d0cc8,'stats':{'totalMessages':_0x57eab8[_0x213f39(0x5d9,0x5a0)],'extractedPatterns':_0x4b2fa7[_0x213f39(0x5d9,0x666)],'filteredSensitive':_0x381694,'processingTimeMs':Date['now']()-_0xb5ac95}};}function extractErrorSolutions(_0x38b5d8,_0x2b238c){function _0x35d0a0(_0x254eba,_0x61fd1a){return _0x5e897f(_0x254eba- -0x1cc,_0x61fd1a);}const _0x4f8529={'doqJr':'import\x20','Epkyj':_0x35d0a0(-0x116,-0xb6),'YQufD':'class\x20','XBVtY':_0x35d0a0(-0xcc,-0x118),'zdOcX':'let\x20','NOenB':'var\x20','uBIvP':_0x574712(0x2e5,0x2f8),'ykDub':_0x35d0a0(-0x95,-0x81),'rpTme':'for\x20','WNMDD':_0x35d0a0(-0x154,-0x17d),'QrvQC':function(_0x30c253,_0x24568e){return _0x30c253/_0x24568e;},'tWtXl':function(_0x60f767,_0x2e5d1d){return _0x60f767+_0x2e5d1d;},'QBoyP':function(_0xaaa8cb,_0x16c089){return _0xaaa8cb<_0x16c089;},'quRqU':function(_0x1430eb,_0x95e692){return _0x1430eb!==_0x95e692;},'fzzZv':_0x574712(0x2ae,0x2f1),'ExkFP':function(_0x4d15fc,_0x4b318b){return _0x4d15fc(_0x4b318b);},'Oonxt':function(_0x893078,_0x5bc2ca,_0x22c5f4){return _0x893078(_0x5bc2ca,_0x22c5f4);},'FokqV':function(_0x5266c4,_0x3b36e4){return _0x5266c4!==_0x3b36e4;},'NGaoq':_0x35d0a0(-0xb8,-0x105),'RZMhM':_0x35d0a0(-0x14a,-0xff)};function _0x574712(_0x5c7d7e,_0x177c3b){return _0x5e897f(_0x177c3b-0x1df,_0x5c7d7e);}const _0xb6ead2=[];for(let _0x3cc581=0x0;_0x3cc581<_0x38b5d8[_0x574712(0x283,0x307)];_0x3cc581++){const _0x2c2a82=_0x38b5d8[_0x3cc581],_0x4cb9db=getFullText(_0x2c2a82),_0x1552dc=ERROR_INDICATORS[_0x574712(0x2ba,0x298)](_0x5eef94=>_0x4cb9db[_0x574712(0x274,0x227)](_0x5eef94));if(!_0x1552dc)continue;const _0x2c032f=_0x4cb9db[_0x574712(0x26d,0x2cd)]('\x0a'),_0x18dab4=_0x2c032f[_0x574712(0x2a3,0x2d6)](_0x7f74ec=>{const _0x2c1492=_0x7f74ec['trim']();function _0x63a0af(_0x3ee965,_0x1a28c9){return _0x574712(_0x3ee965,_0x1a28c9- -0x305);}function _0x731333(_0x3d2992,_0x4c7948){return _0x574712(_0x3d2992,_0x4c7948-0x171);}return _0x7f74ec[_0x731333(0x47a,0x3fb)]('\x20\x20')||_0x7f74ec[_0x63a0af(-0x10b,-0x7b)]('\x09')||_0x2c1492['startsWith'](_0x4f8529[_0x731333(0x4a0,0x455)])||_0x2c1492['startsWith'](_0x4f8529[_0x63a0af(-0xc5,-0xa1)])||_0x2c1492[_0x731333(0x392,0x3fb)](_0x4f8529[_0x731333(0x42f,0x467)])||_0x2c1492[_0x731333(0x3a4,0x3fb)](_0x4f8529[_0x63a0af(-0xfc,-0xce)])||_0x2c1492[_0x63a0af(-0xd2,-0x7b)](_0x4f8529[_0x63a0af(-0x114,-0x10b)])||_0x2c1492[_0x731333(0x41b,0x3fb)](_0x4f8529[_0x731333(0x3d3,0x3d1)])||_0x2c1492[_0x731333(0x41f,0x3fb)](_0x4f8529[_0x63a0af(-0x68,0x3)])||_0x2c1492[_0x63a0af(-0x55,-0x7b)](_0x4f8529[_0x731333(0x450,0x423)])||_0x2c1492[_0x63a0af(-0x2a,-0x7b)](_0x4f8529[_0x63a0af(-0x126,-0x98)])||_0x2c1492[_0x63a0af(-0xba,-0x7b)](_0x4f8529['WNMDD']);})[_0x35d0a0(-0xa4,-0x2a)];if(_0x2c032f[_0x574712(0x30b,0x307)]>0x0&&_0x4f8529['QrvQC'](_0x18dab4,_0x2c032f['length'])>0.5)continue;const _0x3fdc0c=_0x4cb9db[_0x35d0a0(-0xde,-0xa2)]('\x0a')['find'](_0x4e0e16=>ERROR_INDICATORS['some'](_0x5e9440=>_0x4e0e16[_0x35d0a0(-0x184,-0x1f6)](_0x5e9440)));if(!_0x3fdc0c||_0x3fdc0c[_0x574712(0x2aa,0x280)]()[_0x574712(0x2ff,0x307)]<0x14)continue;for(let _0x28a64c=_0x4f8529[_0x574712(0x1a4,0x208)](_0x3cc581,0x1);_0x4f8529[_0x574712(0x23b,0x212)](_0x28a64c,Math[_0x574712(0x248,0x241)](_0x4f8529[_0x574712(0x1d7,0x208)](_0x3cc581,0x5),_0x38b5d8[_0x35d0a0(-0xa4,-0xdb)]));_0x28a64c++){const _0x5a5732=_0x38b5d8[_0x28a64c];if(_0x4f8529[_0x35d0a0(-0x193,-0x13f)](_0x5a5732[_0x35d0a0(-0xa5,-0xf6)],_0x4f8529[_0x35d0a0(-0xf3,-0x72)]))continue;const _0x220913=_0x4f8529[_0x35d0a0(-0x1a1,-0x1af)](getFullText,_0x5a5732),_0x87a56e=Array[_0x35d0a0(-0x183,-0x19d)](_0x5a5732[_0x35d0a0(-0x10f,-0x14d)]['content'])&&_0x5a5732[_0x574712(0x2d4,0x29c)][_0x574712(0x230,0x249)]['some'](_0x4898b5=>_0x4898b5[_0x574712(0x2e6,0x306)]===_0x574712(0x2fd,0x2a9));if(_0x87a56e||_0x220913['length']>0x32){const _0x2be05a=_0x4cb9db[_0x35d0a0(-0x1a2,-0x1f5)](0x0,0x12c),_0x3c2835=_0x220913[_0x574712(0x26d,0x209)](0x0,0x1f4);if(!_0x87a56e&&!_0x4f8529['Oonxt'](verifySolutionRelevance,_0x2be05a,_0x3c2835)){if(_0x4f8529[_0x35d0a0(-0x126,-0x142)](_0x4f8529[_0x35d0a0(-0x1a4,-0x1b9)],_0x4f8529[_0x574712(0x28d,0x2a7)]))continue;else{const _0x321439=_0x53077f['lastIndexO'+'f']('.'),_0xfbde6d=_0x321439>=0x0?_0x2e7fe3[_0x35d0a0(-0x1a2,-0x231)](_0x321439):'',_0x471c80=_0x338098[_0x35d0a0(-0xde,-0x95)]('/'),_0x19a489=_0x471c80[_0x574712(0x22a,0x209)](-0x3,-0x1)[_0x35d0a0(-0x1a0,-0x225)]('/');if(_0xfbde6d)_0x5d3b69[_0x574712(0x31b,0x29b)](_0xfbde6d,(_0x4c44ee[_0x35d0a0(-0x140,-0xb6)](_0xfbde6d)||0x0)+0x1);if(_0x19a489)_0x2a6b39[_0x35d0a0(-0x110,-0x117)](_0x19a489,(_0x3f8978[_0x35d0a0(-0x140,-0xcf)](_0x19a489)||0x0)+0x1);}}_0xb6ead2[_0x574712(0x225,0x23e)]({'content':'[Error]\x20'+_0x2be05a+(_0x35d0a0(-0x19f,-0x17f)+'n]\x20')+_0x3c2835,'category':_0x35d0a0(-0x123,-0x195)+_0x35d0a0(-0x9b,-0x4b),'tier':_0x574712(0x267,0x292),'tags':_0x4f8529[_0x574712(0x292,0x2ee)](extractTags,_0x4cb9db,'error'),'projectPath':_0x2b238c});break;}}}return _0xb6ead2;}function verifySolutionRelevance(_0x2e9dc1,_0x9fbf91){function _0x2673de(_0x3bd2dc,_0x5bb45c){return _0x2d741e(_0x3bd2dc,_0x5bb45c- -0xbc);}const _0x573ad6={'RKFzu':function(_0x15295e,_0x531004){return _0x15295e<_0x531004;},'ulyNv':function(_0x42306e,_0x13bf47){return _0x42306e(_0x13bf47);}};function _0x387f41(_0x135dab,_0x4aa0e5){return _0x2d741e(_0x135dab,_0x4aa0e5- -0x181);}const _0x3e953f=new Set(_0x2e9dc1[_0x2673de(-0x8f,-0xa2)+'e']()[_0x387f41(-0xd5,-0x117)](/\W+/)[_0x387f41(-0xd3,-0x10e)](_0x13aa29=>_0x13aa29[_0x387f41(-0x14e,-0xdd)]>0x3)),_0x9c6d1b=new Set(_0x9fbf91[_0x2673de(-0xb1,-0xa2)+'e']()[_0x2673de(0x12,-0x52)](/\W+/)['filter'](_0x463b31=>_0x463b31['length']>0x3)),_0x3f3c53=[..._0x3e953f][_0x387f41(-0x16e,-0x10e)](_0x604250=>_0x9c6d1b['has'](_0x604250));if(_0x573ad6['RKFzu'](_0x3f3c53['length'],0x2))return![];if(_0x573ad6['ulyNv'](isPureErrorMessage,_0x9fbf91))return![];return!![];}function isPureErrorMessage(_0x3f3995){const _0x51b4a9={'WNdrt':function(_0x2df7c5,_0x8bd78){return _0x2df7c5===_0x8bd78;},'yxtEv':function(_0x2bddf8,_0x139a2e){return _0x2bddf8/_0x139a2e;},'bTZBY':_0x2b4e3c(-0x203,-0x19f),'yEbae':_0x5605ff(0x46a,0x430),'GvhWe':_0x2b4e3c(-0x228,-0x1d2),'aZabc':_0x5605ff(0x405,0x3c0),'PhkJR':'install','BReTd':_0x5605ff(0x49d,0x487)};function _0x2b4e3c(_0x2d6ebd,_0x36fc8c){return _0x5e897f(_0x36fc8c- -0x1f6,_0x2d6ebd);}const _0x1892ae=_0x3f3995[_0x5605ff(0x475,0x447)]('\x0a')[_0x5605ff(0x45b,0x450)](_0x557c39=>_0x557c39[_0x2b4e3c(-0x14b,-0x155)]());if(_0x51b4a9['WNdrt'](_0x1892ae['length'],0x0))return!![];const _0x581168=_0x1892ae[_0x5605ff(0x4a4,0x450)](_0x2db1b5=>/^\s*(at |File |Traceback| File "| raise |>>> )/[_0x2b4e3c(-0x22f,-0x1a9)](_0x2db1b5));if(_0x51b4a9[_0x2b4e3c(-0x163,-0x12f)](_0x581168[_0x2b4e3c(-0x40,-0xce)],_0x1892ae[_0x5605ff(0x44c,0x481)])>0.7)return!![];const _0x181f45=[_0x2b4e3c(-0xf6,-0x160),_0x5605ff(0x46d,0x455),_0x51b4a9[_0x2b4e3c(-0x140,-0xd0)],_0x51b4a9[_0x5605ff(0x420,0x3a5)],_0x51b4a9['GvhWe'],_0x5605ff(0x3dc,0x3fe),_0x51b4a9['aZabc'],_0x51b4a9['PhkJR'],_0x51b4a9[_0x5605ff(0x40a,0x435)],_0x5605ff(0x3ff,0x428),_0x2b4e3c(-0x145,-0x101),_0x5605ff(0x490,0x3fc),_0x2b4e3c(-0x216,-0x190),'해결','수정','변경','설치','시도','사용'];function _0x5605ff(_0x5cdb01,_0x24985d){return _0x5e897f(_0x24985d-0x359,_0x5cdb01);}const _0x385c8f=_0x3f3995[_0x2b4e3c(-0x1cb,-0x158)+'e']();return!_0x181f45[_0x2b4e3c(-0x1a5,-0x13d)](_0xdae4d6=>_0x385c8f['includes'](_0xdae4d6));}function extractCodePatterns(_0x204d36,_0x2be98f){const _0x25237f={'JYdJE':_0x108d3d(0x373,0x3bc),'rCqyn':_0x108d3d(0x319,0x36e),'GilKR':function(_0x68e67,_0x441dd6){return _0x68e67+_0x441dd6;},'ApAXH':function(_0x3581df,_0x36f0cc){return _0x3581df<_0x36f0cc;},'pmDHP':_0x1f722c(0x19a,0x158),'LgYnU':_0x1f722c(0x14e,0x1cf),'CRTBk':'import','ORCxZ':function(_0x4df4dc,_0x5ea745){return _0x4df4dc-_0x5ea745;},'aaYaX':_0x108d3d(0x366,0x34c),'fDkzp':function(_0x2f1e06,_0x4e1b57){return _0x2f1e06>_0x4e1b57;}},_0x4307f9=new Map(),_0x22e421=[_0x25237f[_0x1f722c(0x1bd,0x12d)],_0x108d3d(0x3ab,0x37a),'Grep',_0x108d3d(0x325,0x2be),_0x25237f[_0x108d3d(0x2fc,0x389)]],_0x31ace7=new Map(),_0x2a284d=new Map();for(const _0xfc672f of _0x204d36){if(!Array[_0x1f722c(0xd2,0xb1)](_0xfc672f['message'][_0x1f722c(0xf3,0x164)]))continue;for(const _0x4c1f37 of _0xfc672f[_0x1f722c(0x146,0x14f)][_0x1f722c(0xf3,0x10c)]){if(_0x4c1f37[_0x108d3d(0x3c2,0x3d3)]!==_0x108d3d(0x365,0x3cd)||!_0x4c1f37[_0x108d3d(0x367,0x310)])continue;if((_0x4c1f37['name']==='Write'||_0x4c1f37[_0x1f722c(0x155,0xdc)]===_0x1f722c(0x1c5,0x20e))&&_0x4c1f37['input']){const _0x1abbe3=_0x4c1f37[_0x1f722c(0x16a,0x1d8)][_0x1f722c(0xd4,0x63)];if(_0x1abbe3){const _0x24bcc4=_0x1abbe3[_0x108d3d(0x2fb,0x2a9)+'f']('.'),_0x313e68=_0x24bcc4>=0x0?_0x1abbe3[_0x108d3d(0x2c5,0x26b)](_0x24bcc4):'',_0x150df5=_0x1abbe3[_0x108d3d(0x389,0x2f6)]('/'),_0x499403=_0x150df5['slice'](-0x3,-0x1)[_0x1f722c(0xb5,0x6b)]('/');if(_0x313e68)_0x31ace7['set'](_0x313e68,_0x25237f['GilKR'](_0x31ace7[_0x108d3d(0x327,0x3af)](_0x313e68)||0x0,0x1));if(_0x499403)_0x2a284d[_0x1f722c(0x145,0x131)](_0x499403,(_0x2a284d['get'](_0x499403)||0x0)+0x1);}}if(_0x22e421[_0x1f722c(0xd1,0xc4)](_0x4c1f37['name']))continue;const _0x55364b=_0x4307f9[_0x108d3d(0x327,0x296)](_0x4c1f37[_0x1f722c(0x155,0x122)])??{'count':0x0,'samples':[]};_0x55364b[_0x108d3d(0x39a,0x32d)]++;if(_0x25237f[_0x108d3d(0x38d,0x3c0)](_0x55364b[_0x108d3d(0x3c0,0x428)][_0x1f722c(0x1b1,0x20d)],0x3)&&_0x4c1f37[_0x108d3d(0x37c,0x3d5)]){const _0x12484e=JSON[_0x108d3d(0x2e5,0x280)](_0x4c1f37[_0x1f722c(0x16a,0x105)]);if(_0x12484e[_0x108d3d(0x3c3,0x363)]<=0xc8)_0x55364b[_0x108d3d(0x3c0,0x37d)][_0x108d3d(0x2fa,0x328)](_0x12484e);else{const _0xcdfde2=['error',_0x108d3d(0x331,0x3c3),_0x25237f['pmDHP'],_0x25237f[_0x108d3d(0x386,0x3a6)],'config',_0x25237f[_0x108d3d(0x30c,0x372)],_0x1f722c(0x129,0x9d),_0x108d3d(0x3c6,0x40c),_0x108d3d(0x364,0x36c)],_0x318fbd=_0x12484e[_0x108d3d(0x339,0x39c)+'e']();let _0x2a79da=0x0;for(const _0x28c17f of _0xcdfde2){const _0x120777=_0x318fbd[_0x108d3d(0x2e0,0x2e2)](_0x28c17f);if(_0x120777>=0x0){_0x2a79da=Math[_0x1f722c(0xdd,0xd2)](0x0,_0x25237f[_0x108d3d(0x37e,0x336)](_0x120777,0x32));break;}}_0x55364b[_0x108d3d(0x3c0,0x37a)][_0x108d3d(0x2fa,0x37e)](_0x12484e[_0x1f722c(0xb3,0x137)](_0x2a79da,_0x25237f[_0x108d3d(0x2cc,0x2d2)](_0x2a79da,0xc8)));}}_0x4307f9['set'](_0x4c1f37['name'],_0x55364b);}}function _0x108d3d(_0x12d94e,_0x3a0df2){return _0x5e897f(_0x12d94e-0x29b,_0x3a0df2);}const _0x1c36f2=[];for(const [_0x526073,_0x95e5a8]of _0x4307f9){if(_0x25237f[_0x1f722c(0x17b,0x1fc)](_0x95e5a8[_0x108d3d(0x39a,0x3a7)],0x5))continue;_0x1c36f2[_0x108d3d(0x2fa,0x277)]({'content':_0x1f722c(0xe7,0x11f)+_0x526073+_0x108d3d(0x361,0x38d)+_0x95e5a8[_0x108d3d(0x39a,0x32c)]+(_0x108d3d(0x35e,0x359)+_0x1f722c(0xf4,0xed))+_0x95e5a8[_0x108d3d(0x3c0,0x3e0)][_0x108d3d(0x2c7,0x2b6)]('\x0a'),'category':'code_patte'+'rn','tier':_0x25237f[_0x1f722c(0x11c,0xc4)],'tags':[_0x526073,_0x25237f['LgYnU'],_0x108d3d(0x3ce,0x40e)],'projectPath':_0x2be98f});}function _0x1f722c(_0x8cbfb0,_0x2f10e1){return _0x5e897f(_0x8cbfb0-0x89,_0x2f10e1);}if(_0x25237f[_0x1f722c(0x1c3,0x20a)](_0x31ace7[_0x108d3d(0x2cf,0x2fa)],0x0)){const _0x509f29=[..._0x31ace7['entries']()][_0x108d3d(0x392,0x346)](([,_0x4b1b71])=>_0x4b1b71>=0x3)[_0x1f722c(0x16b,0x127)]((_0x4c1c6f,_0x3d2765)=>_0x3d2765[0x1]-_0x4c1c6f[0x1])[_0x1f722c(0xb3,0x13c)](0x0,0x5);if(_0x509f29[_0x1f722c(0x1b1,0x19f)]>0x0){const _0x45d139=[..._0x2a284d[_0x108d3d(0x391,0x333)]()][_0x108d3d(0x37d,0x3e8)]((_0xa47357,_0x28bcb2)=>_0x28bcb2[0x1]-_0xa47357[0x1])[_0x1f722c(0xb3,0xfb)](0x0,0x3);_0x1c36f2[_0x1f722c(0xe8,0x90)]({'content':_0x1f722c(0x179,0x1cd)+_0x108d3d(0x308,0x393)+'ttern:\x20'+_0x509f29['map'](([_0x3f428a,_0x444ac1])=>_0x3f428a+'('+_0x444ac1+')')[_0x108d3d(0x2c7,0x251)](',\x20')+'.\x20'+('Directorie'+_0x108d3d(0x36b,0x3b0)+_0x45d139[_0x1f722c(0x10c,0x18e)](([_0x273213,_0xeacd88])=>_0x273213+'('+_0xeacd88+')')['join'](',\x20')),'category':_0x1f722c(0x110,0xf7)+'rn','tier':_0x25237f[_0x1f722c(0x11c,0x176)],'tags':[_0x108d3d(0x324,0x376)+'rn','file-modif'+_0x1f722c(0x176,0xed),..._0x509f29[_0x108d3d(0x31e,0x324)](([_0x53375c])=>_0x53375c[_0x108d3d(0x315,0x38f)]('.',''))],'projectPath':_0x2be98f});}}return _0x1c36f2;}function extractDecisions(_0x6b072d,_0x48a692){function _0xb2dda0(_0x3bb4cd,_0x56436c){return _0x2d741e(_0x3bb4cd,_0x56436c- -0xe3);}const _0x2e9d23={'OMPfM':function(_0x78bcc9,_0x550433){return _0x78bcc9<_0x550433;},'cMJrV':'CHANGELOG','zxGDK':_0x2daf02(-0x11f,-0x12e)},_0x4ccfa9=[];for(const _0x31609b of _0x6b072d){const _0x66b039=getFullText(_0x31609b);if(_0x2e9d23[_0xb2dda0(-0x61,-0xbd)](_0x66b039[_0x2daf02(-0x88,-0xb0)],0x32))continue;if(_0x66b039[_0x2daf02(-0x105,-0x10a)](_0x2daf02(-0x135,-0x106))||_0x66b039[_0xb2dda0(-0x1ae,-0x11f)](_0x2e9d23[_0x2daf02(-0x156,-0x12a)])||/v\d+\.\d+\.\d+/['test'](_0x66b039))continue;const _0x3478e4=_0x66b039[_0xb2dda0(-0xf2,-0xed)](/```[\s\S]*?```/g,'')[_0xb2dda0(-0x71,-0xc6)]();if(!_0x3478e4)continue;const _0x2123e4=_0x3478e4[_0xb2dda0(-0x38,-0xc9)+'e'](),_0xbf215=STRONG_DECISION_KEYWORDS['filter'](_0x519720=>_0x2123e4['includes'](_0x519720['toLowerCas'+'e']()))[_0x2daf02(-0x88,-0x107)],_0x155555=WEAK_DECISION_KEYWORDS[_0x2daf02(-0xb9,-0x77)](_0x3294e2=>_0x2123e4[_0xb2dda0(-0xfb,-0x11f)](_0x3294e2['toLowerCas'+'e']()))[_0x2daf02(-0x88,-0xbf)];if(_0xbf215<0x1&&_0x2e9d23[_0xb2dda0(-0x56,-0xbd)](_0x155555,0x2))continue;_0x4ccfa9[_0x2daf02(-0x151,-0x191)]({'content':_0x3478e4[_0x2daf02(-0x186,-0x123)](0x0,0x320),'category':_0x2e9d23[_0x2daf02(-0xfc,-0x157)],'tier':_0xb2dda0(-0xbc,-0x9c),'tags':extractTags(_0x3478e4,_0x2daf02(-0x11f,-0xe0)),'projectPath':_0x48a692});}function _0x2daf02(_0x32034a,_0x5b0bc8){return _0x2d741e(_0x5b0bc8,_0x32034a- -0x12c);}return _0x4ccfa9;}const CONTEXT_KEYWORDS=[_0x2d741e(-0xa2,-0x6c),_0x2d741e(0x4e,0x8f),_0x5e897f(0xf9,0x18b),_0x2d741e(-0xc9,-0x6e)+'t',_0x5e897f(0x10e,0x150)+_0x5e897f(0x131,0x1b0),'설정','설치',_0x5e897f(0x56,0x67),_0x5e897f(0x30,0xbf)],LEARNING_KEYWORDS=[_0x2d741e(0xb7,0x3e),_0x2d741e(0x8f,0x86),_0x5e897f(0x50,-0x28),_0x5e897f(0x23,-0x1c),'figured\x20ou'+'t','discovery',_0x2d741e(-0x85,-0x27),'배웠','깨달','발견',_0x2d741e(0xbf,0x3d),_0x5e897f(0x106,0xef)];function extractContexts(_0x1212a8,_0x36a40b){const _0x193c90={'wPAje':function(_0x21a1ec,_0xae5591){return _0x21a1ec!==_0xae5591;},'mTPsw':'system','aOLxx':function(_0x2a87d3,_0x461c2f){return _0x2a87d3<_0x461c2f;},'Elqei':'<system-re'+_0x172e60(0x8c,0xb2),'ooPls':function(_0x1fdd36,_0x6788e9){return _0x1fdd36<_0x6788e9;},'LnXxh':'context','TFrQC':_0x32f54a(0xe2,0x6e)};function _0x32f54a(_0x63bf73,_0x1bb0a6){return _0x5e897f(_0x1bb0a6- -0x5d,_0x63bf73);}const _0x4371d4=[];for(const _0x6aad5b of _0x1212a8){if(_0x193c90['wPAje'](_0x6aad5b['type'],_0x172e60(-0x44,-0x67))&&_0x6aad5b[_0x172e60(0xb1,0xc1)]!==_0x172e60(-0x13,-0xa4))continue;if(_0x6aad5b[_0x32f54a(0xe2,0x60)][_0x32f54a(-0xa0,-0x3e)]===_0x193c90[_0x32f54a(0xe9,0x80)])continue;const _0x2026ff=getFullText(_0x6aad5b);if(_0x193c90['aOLxx'](_0x2026ff['length'],0x32))continue;if(_0x2026ff['includes'](_0x193c90['Elqei']))continue;if(_0x2026ff['includes']('CLAUDE.md')&&_0x2026ff[_0x172e60(0xb2,0x91)]>0x1f4)continue;const _0x15736c=_0x2026ff['toLowerCas'+'e'](),_0x5d6300=CONTEXT_KEYWORDS[_0x172e60(0x81,0x6e)](_0x2198d2=>_0x15736c[_0x172e60(-0x2e,-0x7b)](_0x2198d2[_0x172e60(0x28,0x91)+'e']())),_0xf5116d=_0x1212a8[_0x32f54a(-0x78,-0x18)](_0x6aad5b);(_0x193c90[_0x172e60(-0x51,0x25)](_0xf5116d,0x3)||_0x5d6300['length']>=0x2)&&_0x4371d4['push']({'content':_0x2026ff['slice'](0x0,0x3e8),'category':_0x193c90[_0x172e60(0x24,-0x42)],'tier':_0x193c90[_0x32f54a(-0x32,0x4b)],'tags':extractTags(_0x2026ff,_0x172e60(0x74,0x75)),'projectPath':_0x36a40b});}function _0x172e60(_0x267769,_0x4ad16e){return _0x5e897f(_0x267769- -0x76,_0x4ad16e);}return _0x4371d4;}function extractConventions(_0x44d96e,_0x3ad2d3){const _0x25e628={'hXupl':_0x2a952f(0x1f2,0x1d8),'TXdHn':function(_0x28d2b3,_0x5a4c06){return _0x28d2b3!==_0x5a4c06;},'Ursau':_0x2a952f(0x2d2,0x243),'IxWhG':function(_0x58624a,_0x29ac54){return _0x58624a<_0x29ac54;},'eOuyl':_0x589263(0xff,0x17f),'jNqNY':_0x589263(0x9b,0x6c),'xWjtF':_0x589263(0xdb,0xb8),'BKitz':function(_0x4bb8fb,_0x4a3551,_0x4a6285){return _0x4bb8fb(_0x4a3551,_0x4a6285);}};function _0x2a952f(_0x8c9ee2,_0x17c553){return _0x2d741e(_0x17c553,_0x8c9ee2-0x244);}const _0x3fc640=[];for(const _0x4716b6 of _0x44d96e){if(_0x4716b6[_0x589263(0x137,0xbd)]!==_0x25e628[_0x589263(0xe4,0x9b)]&&_0x25e628[_0x2a952f(0x262,0x26b)](_0x4716b6[_0x2a952f(0x2e7,0x27f)],_0x25e628[_0x2a952f(0x1f8,0x215)]))continue;const _0x4b8e08=getFullText(_0x4716b6);if(_0x25e628[_0x589263(0x9d,0x32)](_0x4b8e08[_0x589263(0x138,0xe2)],0x14))continue;if(_0x4716b6['type']===_0x25e628['Ursau']){if('xdaKf'!==_0x25e628['eOuyl']){const _0x1b540b=/(?:should|must|always|never|recommend|규칙|원칙|필수|금지)/i[_0x589263(0x5d,0x16)](_0x4b8e08);if(!_0x1b540b)continue;}else return[];}const _0x44c156=CONVENTION_KEYWORDS['some'](_0xf31056=>_0x4b8e08[_0x2a952f(0x25e,0x1e4)+'e']()[_0x2a952f(0x208,0x224)](_0xf31056[_0x2a952f(0x25e,0x1d1)+'e']()));if(!_0x44c156)continue;_0x3fc640[_0x589263(0x6f,-0x4)]({'content':_0x4b8e08[_0x2a952f(0x1ea,0x21c)](0x0,0x1f4),'category':_0x25e628[_0x589263(0x85,0x59)],'tier':_0x25e628[_0x589263(0xad,0xe1)],'tags':_0x25e628[_0x589263(0x111,0x11d)](extractTags,_0x4b8e08,_0x25e628['jNqNY']),'projectPath':_0x3ad2d3});}function _0x589263(_0x5027e8,_0x27f092){return _0x2d741e(_0x27f092,_0x5027e8-0x94);}return _0x3fc640;}function extractLearnings(_0x43d60d,_0x22fb33){const _0x3e60b9={'WXhrs':function(_0x175bf3,_0x324912){return _0x175bf3!==_0x324912;},'hfiYM':function(_0x5b5fac,_0x476126){return _0x5b5fac!==_0x476126;},'qvewV':function(_0x34b7d8,_0x1d84cd,_0x48c2e8){return _0x34b7d8(_0x1d84cd,_0x48c2e8);}},_0x39b3aa=[];function _0x141b3f(_0xb4f372,_0x1cf44a){return _0x5e897f(_0xb4f372- -0x293,_0x1cf44a);}function _0x39312d(_0x3e3d17,_0x2f7aed){return _0x5e897f(_0x2f7aed- -0x28a,_0x3e3d17);}for(const _0x1f1baa of _0x43d60d){if(_0x3e60b9['WXhrs'](_0x1f1baa['type'],'human')&&_0x3e60b9[_0x39312d(-0x25e,-0x253)](_0x1f1baa['type'],_0x141b3f(-0x181,-0x1a9)))continue;const _0x1265ef=getFullText(_0x1f1baa);if(_0x1265ef['length']<0x1e)continue;const _0x2bfddd=LEARNING_KEYWORDS[_0x39312d(-0x1a4,-0x1d1)](_0x1e74f7=>_0x1265ef[_0x39312d(-0x1bb,-0x1ec)+'e']()[_0x39312d(-0x215,-0x242)](_0x1e74f7[_0x39312d(-0x26e,-0x1ec)+'e']()));if(!_0x2bfddd)continue;_0x39b3aa[_0x39312d(-0x27e,-0x22b)]({'content':_0x1265ef[_0x39312d(-0x204,-0x260)](0x0,0x320),'category':_0x39312d(-0x1b3,-0x1a2),'tier':_0x141b3f(-0x1e0,-0x266),'tags':_0x3e60b9[_0x39312d(-0x266,-0x20b)](extractTags,_0x1265ef,_0x39312d(-0x12a,-0x1a2)),'projectPath':_0x22fb33});}return _0x39b3aa;}function getFullText(_0x5dc69a){const _0x5b4c66={'tieoP':function(_0x20c271,_0x4cfff0){return _0x20c271===_0x4cfff0;},'ghQbF':function(_0x34039b,_0x10eed2){return _0x34039b===_0x10eed2;},'UnyKI':_0x43f5ca(0x4a0,0x42b),'dIBFL':_0x43f5ca(0x474,0x420),'KHhoY':function(_0x158513,_0x95bc63){return _0x158513===_0x95bc63;}};function _0x43f5ca(_0x27a799,_0x5961ee){return _0x2d741e(_0x27a799,_0x5961ee-0x420);}function _0x3b5bf6(_0x1c1ba1,_0x101708){return _0x2d741e(_0x1c1ba1,_0x101708-0x2b0);}if(_0x5b4c66['KHhoY'](typeof _0x5dc69a['message'][_0x3b5bf6(0x319,0x296)],'string'))return _0x5dc69a[_0x43f5ca(0x481,0x459)][_0x43f5ca(0x47a,0x406)];return _0x5dc69a['message']['content'][_0x3b5bf6(0x2c7,0x2af)](_0x59a31b=>{function _0x58c580(_0x4a1aa3,_0x305f11){return _0x43f5ca(_0x305f11,_0x4a1aa3- -0x2e7);}function _0x18af84(_0x574740,_0x153a3b){return _0x43f5ca(_0x574740,_0x153a3b- -0x2fe);}if(_0x5b4c66[_0x58c580(0xd6,0x145)](_0x58c580(0x1d6,0x1f0),_0x5b4c66['UnyKI'])){if(_0x5a8287['type']===_0x58c580(0x139,0x15e)&&_0x48fdc3['text'])return _0x4b6b63[_0x58c580(0x139,0xc5)];if(_0x5b4c66[_0x58c580(0x1b0,0x1fe)](_0x52f3fb['type'],'tool_resul'+'t')&&_0x1dc230[_0x18af84(0x157,0x108)])return _0x1f48dc['content'];return'';}else{if(_0x5b4c66[_0x18af84(0x222,0x199)](_0x59a31b[_0x18af84(0x138,0x1c5)],_0x5b4c66[_0x58c580(0xd7,0x114)])&&_0x59a31b[_0x58c580(0x139,0x1cb)])return _0x59a31b[_0x58c580(0x139,0x1b4)];if(_0x5b4c66['ghQbF'](_0x59a31b[_0x18af84(0x1f5,0x1c5)],_0x58c580(0x1d1,0x1f9)+'t')&&_0x59a31b['content'])return _0x59a31b[_0x18af84(0x169,0x108)];return'';}})[_0x43f5ca(0x4f1,0x493)](Boolean)[_0x3b5bf6(0x28d,0x258)]('\x0a');}const TECH_NAMES=[_0x5e897f(0x6f,0x4a),_0x2d741e(0xe1,0x91),'angular',_0x5e897f(0x70,0xec),_0x5e897f(0x132,0xdd),_0x5e897f(0x2e,-0x31),_0x5e897f(0x9f,0xb7),'postgresql',_0x2d741e(-0x30,0xc),_0x5e897f(0x77,0x3b),'docker',_0x5e897f(0x130,0x1a0),_0x5e897f(0x11b,0x15c),_0x5e897f(0x9b,0xec),_0x5e897f(0xf1,0xe6),'express','next.js',_0x5e897f(0xa4,0xf7),'git',_0x5e897f(0x5b,0x3b),_0x2d741e(0x7a,0x94),_0x2d741e(0x3b,-0x28),_0x2d741e(0x8c,0xa0),'eslint',_0x2d741e(0x34,-0x1b),_0x5e897f(0x3d,0x79),'playwright',_0x5e897f(0xf3,0x164)],WORK_TYPES=[_0x2d741e(0x8b,0x40),'debug',_0x2d741e(0x2f,0x52),_0x5e897f(0x4d,0x90),'review',_0x2d741e(-0x17,0x79),_0x5e897f(0x95,0x1c),'setup','config',_0x5e897f(0x26,-0x2c),_0x2d741e(-0xd,0x7f),'fix',_0x2d741e(0x57,0x3b),_0x5e897f(0xdf,0x105)],LOW_VALUE_EXTS=new Set(['md',_0x5e897f(0x3c,-0x40),_0x5e897f(0x53,-0x3),_0x5e897f(0x46,0x7a),_0x5e897f(0x11f,0x141),_0x5e897f(0xec,0x84),_0x5e897f(0x2f,0xa8),_0x2d741e(-0x5e,-0x6d)]),MEANINGFUL_EXTS=new Set(['py','ts',_0x5e897f(0x64,0x26),'js',_0x2d741e(-0x44,-0x32),'java','go','rs','rb','swift','kt']);function extractTags(_0x165a78,_0x3be90f){const _0x2867b8={'MQNLt':function(_0x114ddd,_0x997542){return _0x114ddd===_0x997542;},'CaKLD':_0x398f35(-0x1c6,-0x224)},_0xc609f5=[_0x3be90f],_0x30a8be=_0x165a78[_0x3aa499(-0x1f3,-0x23b)](/[\w/.-]{1,200}\.\w{1,10}/g);function _0x3aa499(_0x2cd40a,_0x1705cc){return _0x2d741e(_0x1705cc,_0x2cd40a- -0x221);}if(_0x30a8be){const _0x16506b=new Set(_0x30a8be[_0x398f35(-0x1fa,-0x259)](_0x4e5c33=>_0x4e5c33['split']('.')[_0x398f35(-0x1a8,-0x1d4)]())['filter'](_0x44b061=>_0x44b061[_0x3aa499(-0x17d,-0x105)]<=0x5&&_0x44b061[_0x3aa499(-0x17d,-0xeb)]>0x1)['filter'](_0x314c1e=>!/^\d+$/['test'](_0x314c1e))[_0x398f35(-0x186,-0x203)](_0x282150=>!LOW_VALUE_EXTS[_0x398f35(-0x1e9,-0x1d7)](_0x282150['toLowerCas'+'e']()))[_0x3aa499(-0x1ae,-0x1f3)](_0x4dfcaa=>MEANINGFUL_EXTS[_0x3aa499(-0x211,-0x28d)](_0x4dfcaa[_0x3aa499(-0x207,-0x1e3)+'e']())));_0xc609f5[_0x398f35(-0x21e,-0x26a)](...[..._0x16506b]['slice'](0x0,0x2));}const _0x510f20=_0x165a78[_0x3aa499(-0x207,-0x1b7)+'e']();for(const _0xffbb7b of TECH_NAMES){_0x510f20[_0x398f35(-0x235,-0x2a0)](_0xffbb7b)&&_0xc609f5[_0x3aa499(-0x246,-0x2ab)](_0xffbb7b);}for(const _0x451c64 of WORK_TYPES){if(_0x510f20[_0x398f35(-0x235,-0x1ec)](_0x451c64)){if(_0x2867b8[_0x3aa499(-0x240,-0x1dc)](_0x2867b8[_0x3aa499(-0x27e,-0x2b5)],_0x2867b8['CaKLD'])){_0xc609f5[_0x3aa499(-0x246,-0x237)](_0x451c64);break;}else return _0x265260(_0x6fb218,0.7);}}function _0x398f35(_0x1adba3,_0x2079c4){return _0x2d741e(_0x2079c4,_0x1adba3- -0x1f9);}return[...new Set(_0xc609f5)]['filter'](_0x53ce4=>_0x53ce4[_0x3aa499(-0x17d,-0x1ce)]>=0x2&&!/^\d+$/[_0x398f35(-0x230,-0x1f0)](_0x53ce4))[_0x398f35(-0x1fa,-0x259)](_0x30f469=>_0x30f469[_0x3aa499(-0x207,-0x265)+'e']())[_0x3aa499(-0x27b,-0x299)](0x0,0x5);}function deduplicateMemories(_0x123fdf){return deduplicateByContent(_0x123fdf,0.7);}const CLASSIFIABLE_CATEGORIES=[_0x2d741e(-0x6a,0x25)+_0x2d741e(0xcd,0xad),_0x5e897f(0x87,0x41)+'rn',_0x5e897f(0x91,0x36),'convention','rule',_0x2d741e(0x18,0x62)+_0x2d741e(0x18,0x7a),_0x2d741e(0xcf,0x64)];function _0x1ef3(){const _0x4e5df8=['Dgv4Da','rxbREwO','DgLVBI9JB2rLxW','y29Kzv9Wyxr0zq','BwvTB3jPzxm','y29Kzs1Wyxr0zq','v2vIrMv0y2G','y29UDMvUDgLVBG','z2v0','sxHxAeC','CNbuBwu','BLbqB0G','BxLZCwW','zgvJAxnPB24','vLbIrNq','ywfzyvG','AgfZ','BwLNCMf0zq','zML4','ioUWMo2zMcaO66Ei7ygS64UK7jQ0ia','DxvPza','vhjHy2vIywnR','tg5yEgG','z2nW','sMTWr0m','EfDQDey','Dg9mB3DLCKnHCW','AMf2yq','zxHWB3j0','DhjPBq','vfHKsg4','BwfRzsbZDxjL','BM9Kzs5QCW','y2HHBMDL','rM9RCvy','mtfvzfDos3q','vezYuum','zxjYB3jFC29SDq','t01qzK0','C3rHCNrZv2L0Aa','DgLTzxn0yw1W','7iUSioYNGoYlNEYDHcaZFJxQSjW','ioUcMoYKKEYxKcdSNkdSMQNTLAaG7zw1','zxHJzxb0Aw9U','CNvSzq','rMfPBgvK','Bwf0y2G','zxbPC29KAwm','ENHhreS','nJyXmdqWtendEKHr','zNvUy3rPB24G','C3rcqNi','mJfer0rSDwO','C29Tzq','y2HVC2u','qw9gAMS','C2v0','BwvZC2fNzq','zxjYB3i','Aw1WBgvTzw50','u2L1Cey','7jwm6RkmioUqKa','BgvHCM5Lza','ihrPBwvZlIbtyq','zgvWBg95','Cgf0DgvYBG','iIb1C2vKia','ExH0rxy','uLPnAe0','y2XHC3m','Dg9VBf91C2u','C2vTyw50Awm','BMfTzq','rKHby0S','y2f0zwDVCNK','C2HVDwXK','CZOG','mtq4mtuYmeLwwgTbuG','mJaXmtuXoe55D09Quq','EwTeDwi','AfH1CgW','Cg9W','CMvMywn0B3i','Dhj5','uMvHza','zNP6wNy','qufXu1u','66Y07kgW6Rg0','qLjLvgq','BvrqC3C','7l2u65oCioU4LoUHNsdSL4BSNBqPoG','DxbNCMfKzq','mZG5ntiXmLHuzMXPDW','Aw5WDxq','C29YDa','t1jdEfO','wxP6B3O','DMfYia','ChjVAMvJDf9RBG','ru9LEvi','BgvHCM5PBMC','DgfNCYi6ifSIlG','y29UDgv4Da','tgDzBLu','Eg1S','AwnHDgLVBG','C3bSAxq','AMDgyue','q29KzsbTB2rPzG','zMfZDgfWAq','qxbbweG','C3fSAxrL','DgvK','BMvLzcb0BW','zw50CMLLCW','zMLSDgvY','CMf0AgvYihrOyq','y29UzMLNDxjL','nhnWEffLvq','DgLLB1a','C29SDMu','B3b0Aw1PEMu','B3DSzwrNzq','y291BNq','y29UC3qG','qKTPDhO','BwLUzgvYpG','CMvSzwfZzq','Bgv0ia','zg9XsNi','7j207zw07zAi','icjJB250zw50iG','cGPku09oioUWSoYxToUNJa','B3b0zwqGzM9Y','veLm','qvv5tgm','vg9WAee','mJe1nZm5BhPgB0Xk','Aw5PDgLHBgL6yq','t29UEhq','r2XVyG','C29SDxrPB24','yxnZAxn0yw50','Aw5ZDgfSBa','BuHMr0O','DNvL','BNrLBNqSihrHzW','wvf1zKq','CMvZDa','zgvMia','Aw5ZDgvHzcbVzG','yxDZ','Dg9VBf9Yzxn1Ba','BMv2zxi','6RkW7kcv7zAi','EwfTBa','y2XHC3nPzNK','z3zmBxu','zMfPBgvK','Esi6iciUlI4Ila','DML0zq','C2fTCgXLCW','yLrAqLK','DhLWzq','BgvUz3rO','DujjDLa','zwrNzs9JB252zq','zNvUy3rPB24','BM93','y2XHC3mG','Aw5ZDgvHza','66gCioUWMo2zMc4kcUUmGo2zLdO','A3vIzxjUzxrLCW','DgLVBG','AMf2yxnJCMLWDa','Dg9VBc11C2fNzq','sLLKsKu','64UK7j2mioQWNoUWNcdRJidTMztSL5dSHjW','wxP2s1y','AwyG','weXWBKi','xtOG','zKrRENa','uK9AsNi','rwrPDa','zw52AxjVBM1LBG','y3nZ','C2v0Dxa','zuXVsvy','CMHuwM0','EMrpy1G','zgvJAwrLza','AMvJDf9RBM93Ba','t2r4sva','CM9Szq','C3rYyxrLz3K','z2HryKy','zeLcrKW','Dw5KzxjZDg9Vza','DxnL','B29qBhm','yNvPBgq','q2flteq','tKDHB3e','DfD0wgW','C2XPy2u','rxHRrLa','AM9PBG','cGPBu29SDxrPBW','ChL0Ag9U','AhrTBa','7lsi6RIW7zMu','r2LSs1i','AhvTyw4','uujVEva','C2L6zq','C3rYAw5N','BgXTlwv4DhjHyW','AgzPwu0','vxjZyxu','CxvsCvu','rxjYB3i','qxnZAxn0yw50','DhH0','AMvZDa','u2niq0y','DhjHy2vIywnR','Bvzvyva','rvjst1i','vxnLCG','yxbWCM9Hy2G','mJbYAMTiq2u','Aw5KzxHpzG','Ew1S','mJeYnJnfueTSv2W','Aw5JBhvKzxm','AxnbCNjHEq','C3rYAw5NAwz5','zMLSzv9WyxrO','EuvIywu','DgvZDa','ChjLzMvY','rLPYr3O','CMvHBgL6zwq','Dw5RBM93BG','ANn4','ANnVBG','Bwf4','ote2odG1ruvOve93','7zMy6Rk97isK7kcv','CMvZB2X2zq','wejwDfK','y29TCgXLDgu','y01kCLy','z3jHCgHXBa','D2vICgfJAW','Aw5ZAwDODa','vg9VBcaI','ChvZAa','BgfZDeLUzgv4tW','CKnXEw4','BwLU','C3LZDgvT','Dhn4','tvfothq','zw5ZDxjL','DxbKyxrL','rxHJzxb0Aw9U','DML0zxn0','y29UDgvUDa','BxbSzxm6cG','C+ULVcbku09oioUWSoYxTa','AwnHDgLVBIbWyq','7isG7yoD7zAi','CMvHy3q','DhLWzxnJCMLWDa','q1juqMS','DgfNCW','EgPYAKe','qKzNv3m','AK5XtLK','EKzwtw4','CMvKAxm','CMv0DxjUia','y2LZAw9Ul3bYBW','CMvWBgfJzq','zgLMzIaTlwDPDa','mZjrBvLnEhi','BeT0vuO','v2vIu2vHCMnO','CxzLD1y','y1nXBhu','tK9LBKi','swnlveq','BwfW'];_0x1ef3=function(){return _0x4e5df8;};return _0x1ef3();}async function _llmExtractSupplemental(_0x31f903,_0x252bef,_0x4ad015){function _0x521661(_0x278378,_0xe49e4c){return _0x2d741e(_0xe49e4c,_0x278378-0xce);}const _0x559aa4={'FZrGz':_0x521661(0x180,0x19c),'JkpGC':function(_0x433af5,_0x2b90bf){return _0x433af5===_0x2b90bf;},'QbXJD':_0x65a47f(0x130,0x134),'pSArg':'User','SiupF':_0x521661(0x85,0xf4),'ScHCF':'[{\x22categor'+_0x65a47f(0x1ae,0x225)+_0x521661(0x151,0x1c3)+':\x20\x22...\x22,\x20\x22'+_0x521661(0x133,0x179)+'..\x22]}]'},_0x14d4f7=_0x31f903[_0x65a47f(0x12c,0x12c)](-0x14),_0x125748=_0x14d4f7['map'](_0x446823=>{function _0x4b1b8f(_0x3e6459,_0x51daca){return _0x521661(_0x51daca-0x42b,_0x3e6459);}function _0x29896c(_0x17d7f9,_0xd1165b){return _0x521661(_0xd1165b-0x56,_0x17d7f9);}if('ALWGN'!==_0x559aa4[_0x4b1b8f(0x518,0x4c4)]){const _0x4b1141=_0x559aa4[_0x4b1b8f(0x513,0x511)](_0x446823[_0x4b1b8f(0x52a,0x59c)],_0x559aa4['QbXJD'])?_0x559aa4['pSArg']:_0x559aa4[_0x29896c(0x1ee,0x160)],_0x414806=getFullText(_0x446823)['slice'](0x0,0x1f4);return'['+_0x4b1141+_0x29896c(0x219,0x1d9)+_0x414806;}else _0x39b072['samples'][_0x4b1b8f(0x457,0x4d4)](_0x4a516e);})[_0x65a47f(0x260,0x1f9)](_0x1a8a0c=>_0x1a8a0c[_0x521661(0x172,0x16e)]>0xa)['join']('\x0a\x0a')[_0x521661(0x74,0x4b)](0x0,0x1770);if(!_0x125748)return[];function _0x65a47f(_0x378491,_0x1a9e35){return _0x2d741e(_0x378491,_0x1a9e35-0x186);}const _0x41abcc=_0x559aa4[_0x521661(0x88,0x3f)],_0x528df2=_0x521661(0x17f,0x1ba)+_0x65a47f(0x23e,0x1b0)+_0x65a47f(0x18d,0x1af)+'\x20추출하세요.\x0a각각'+'\x20category('+_0x65a47f(0x137,0x1ab)+_0x521661(0xd0,0x144)+'pattern/de'+_0x521661(0xc3,0x33)+_0x521661(0x67,-0x25)+_0x65a47f(0x281,0x22c)+'ntion),\x20co'+_0x65a47f(0x233,0x218)+_0x65a47f(0x1a6,0x16e)+_0x521661(0x179,0xf6)+'\x0a'+_0x125748+(_0x65a47f(0x273,0x20a)+_0x65a47f(0x1b9,0x199)+_0x65a47f(0x252,0x1e0)+'\x0a')+_0x41abcc;try{const _0x284008=await _0x252bef[_0x65a47f(0x14d,0x15b)](_0x528df2),_0x417a38=_0x284008[_0x65a47f(0x109,0x17c)](/```(?:json)?\s*\n?([\s\S]*?)\n?```/g,'$1')[_0x521661(0xeb,0xe8)](),_0xf01d81=JSON['parse'](_0x417a38);if(!Array[_0x65a47f(0x12c,0x14b)](_0xf01d81))return[];return _0xf01d81[_0x521661(0x141,0xd2)](_0x22acd0=>_0x22acd0[_0x521661(0xb4,0x94)]&&_0x22acd0[_0x65a47f(0x13a,0x16c)]['length']>=0x32&&CLASSIFIABLE_CATEGORIES[_0x65a47f(0x1ac,0x14a)](_0x22acd0[_0x65a47f(0x207,0x1d0)]))[_0x521661(0xcd,0x101)](_0x5324ac=>({'content':_0x5324ac[_0x65a47f(0x149,0x16c)][_0x521661(0x74,0x7a)](0x0,0x320),'category':_0x5324ac['category'],'tier':_0x521661(0x115,0xc7),'tags':Array[_0x65a47f(0x118,0x14b)](_0x5324ac[_0x521661(0xbc,0xfa)])?_0x5324ac['tags']['slice'](0x0,0x5):[_0x521661(0x80,0x6b)+_0x521661(0x13e,0x104)],'projectPath':_0x4ad015}));}catch{return[];}}export async function extractMemoriesWithLLM(_0x209938,_0x25fde8,_0x24b604){const _0x67a69e={'lKtUJ':function(_0x4996ea,_0x3ae3a1){return _0x4996ea===_0x3ae3a1;},'Yzzoz':_0x596558(-0x62,-0x10),'woysi':'if\x20','cSqlu':'for\x20','tNUIt':'return\x20','zFVMn':function(_0x276265,_0x566873){return _0x276265<=_0x566873;},'BFgWs':function(_0x4dfe5c,_0x1f7e9e){return _0x4dfe5c>=_0x1f7e9e;},'pXdHU':'DUoHB','EOeyR':'convention','xjrjA':function(_0x164806,_0x2ecfab){return _0x164806<_0x2ecfab;},'eLoIV':_0x25d69d(0x464,0x4ac)},_0x385f73=extractMemories(_0x209938,_0x25fde8);function _0x25d69d(_0x747373,_0x1c491a){return _0x5e897f(_0x1c491a-0x3d2,_0x747373);}if(!_0x24b604)return _0x385f73;function _0x596558(_0x580a64,_0x4919f7){return _0x5e897f(_0x580a64- -0x118,_0x4919f7);}if(_0x67a69e[_0x596558(-0xa2,-0xf6)](_0x385f73[_0x596558(-0x90,-0x25)][_0x25d69d(0x476,0x4fa)],0x3)&&_0x67a69e[_0x596558(-0xa4,-0x37)](_0x209938[_0x596558(0x10,-0x39)],0xa)){if(_0x67a69e['pXdHU']==='SqwQc'){const _0x3497be=xHqGXH[_0x25d69d(0x447,0x44f)](_0x11bd15['type'],'human')?_0x25d69d(0x470,0x414):'Assistant',_0x1dfbc2=_0x4ae730(_0x446bc8)[_0x25d69d(0x3bb,0x3fc)](0x0,0x1f4);return'['+_0x3497be+_0x25d69d(0x510,0x50b)+_0x1dfbc2;}else try{const _0x542c1a=await _llmExtractSupplemental(_0x209938,_0x24b604,_0x25fde8);_0x385f73[_0x596558(-0x90,-0x9f)][_0x596558(-0xb9,-0x108)](..._0x542c1a);}catch{}}const _0x1d1876=[_0x596558(-0x2e,0x33),_0x596558(-0x87,-0x118),_0x67a69e[_0x596558(-0x31,0x42)]];for(let _0x266c89=0x0;_0x67a69e[_0x596558(-0xa5,-0xa2)](_0x266c89,_0x385f73[_0x25d69d(0x3f8,0x45a)][_0x25d69d(0x4c3,0x4fa)]);_0x266c89++){if(!_0x1d1876[_0x25d69d(0x458,0x41a)](_0x385f73['memories'][_0x266c89][_0x596558(-0x4a,0x12)]))continue;try{if(_0x596558(-0x3e,0x4a)===_0x67a69e[_0x25d69d(0x44c,0x3eb)]){const _0x2fc245=await _0x24b604[_0x596558(0x8,-0x53)](_0x385f73[_0x596558(-0x90,-0xba)][_0x266c89][_0x25d69d(0x3f5,0x43c)],CLASSIFIABLE_CATEGORIES);CLASSIFIABLE_CATEGORIES[_0x596558(-0xd0,-0x123)](_0x2fc245)&&(_0x385f73[_0x596558(-0x90,-0xb0)][_0x266c89]={..._0x385f73['memories'][_0x266c89],'category':_0x2fc245});}else{const _0x1ddf2e=_0x2b2b0c[_0x596558(-0x77,-0x89)]();return _0x5832b8[_0x25d69d(0x444,0x47d)]('\x20\x20')||_0x261a07[_0x596558(-0x6d,-0xe6)]('\x09')||_0x1ddf2e[_0x596558(-0x6d,-0xee)]('import\x20')||_0x1ddf2e[_0x596558(-0x6d,-0x3c)](xHqGXH[_0x596558(-0x34,-0xbe)])||_0x1ddf2e['startsWith'](_0x25d69d(0x4bb,0x4ff))||_0x1ddf2e[_0x25d69d(0x40d,0x47d)]('const\x20')||_0x1ddf2e['startsWith'](_0x25d69d(0x4eb,0x4d6))||_0x1ddf2e[_0x596558(-0x6d,-0x72)](_0x25d69d(0x507,0x4b7))||_0x1ddf2e[_0x25d69d(0x50b,0x47d)](_0x25d69d(0x57e,0x4eb))||_0x1ddf2e[_0x25d69d(0x3f0,0x47d)](xHqGXH['woysi'])||_0x1ddf2e['startsWith'](xHqGXH[_0x596558(-0x98,-0x3c)])||_0x1ddf2e['startsWith'](xHqGXH['tNUIt']);}}catch{}}return _0x385f73;}export async function summarizeSession(_0x28a08d,_0x85aac2){const _0x4f7508={'AoFjk':function(_0x25b76d,_0x5bad01){return _0x25b76d===_0x5bad01;},'FHAcK':function(_0x5105b3,_0x2cda0f){return _0x5105b3===_0x2cda0f;}};function _0x4b7854(_0x362552,_0x19b762){return _0x2d741e(_0x19b762,_0x362552-0x229);}function _0x5c6b41(_0x463253,_0x6a931a){return _0x2d741e(_0x463253,_0x6a931a-0x254);}const _0x3944e1=_0x28a08d['filter'](_0x47765e=>_0x47765e[_0x4b7854(0x2cc,0x272)]===_0x5c6b41(0x267,0x2e2))[_0x4b7854(0x228,0x1b0)](_0xd75398=>{function _0x6bfdfb(_0x5b9dda,_0x1eac66){return _0x4b7854(_0x1eac66- -0x427,_0x5b9dda);}function _0x3dead6(_0x50e785,_0x548734){return _0x4b7854(_0x50e785- -0x175,_0x548734);}if(_0x4f7508[_0x6bfdfb(-0x213,-0x1c7)](typeof _0xd75398[_0x6bfdfb(-0x1f6,-0x1c5)][_0x6bfdfb(-0x295,-0x218)],_0x3dead6(0x65,0x4)))return _0xd75398[_0x6bfdfb(-0x232,-0x1c5)][_0x6bfdfb(-0x203,-0x218)];return _0xd75398[_0x6bfdfb(-0x1c1,-0x1c5)]['content']['filter'](_0xce4358=>_0xce4358['type']===_0x6bfdfb(-0x26b,-0x1fe)&&_0xce4358[_0x6bfdfb(-0x1ca,-0x1fe)])[_0x3dead6(0xb3,0x28)](_0xec69ac=>_0xec69ac[_0x6bfdfb(-0x246,-0x1fe)])[_0x6bfdfb(-0x219,-0x256)]('\x0a');})[_0x4b7854(0x29c,0x30d)](_0x3802cd=>_0x3802cd[_0x5c6b41(0x31e,0x2f8)]>0x14)[_0x4b7854(0x1cf,0x250)](0x0,0xa);if(_0x4f7508[_0x4b7854(0x272,0x26b)](_0x3944e1[_0x5c6b41(0x347,0x2f8)],0x0))return'';return _0x85aac2['summarize'](_0x3944e1);}
|