@yuaone/core 0.1.3 → 0.3.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.
Files changed (95) hide show
  1. package/dist/agent-loop.d.ts +152 -0
  2. package/dist/agent-loop.d.ts.map +1 -1
  3. package/dist/agent-loop.js +893 -9
  4. package/dist/agent-loop.js.map +1 -1
  5. package/dist/benchmark-runner.d.ts +141 -0
  6. package/dist/benchmark-runner.d.ts.map +1 -0
  7. package/dist/benchmark-runner.js +526 -0
  8. package/dist/benchmark-runner.js.map +1 -0
  9. package/dist/codebase-context.d.ts +49 -0
  10. package/dist/codebase-context.d.ts.map +1 -1
  11. package/dist/codebase-context.js +146 -0
  12. package/dist/codebase-context.js.map +1 -1
  13. package/dist/constants.d.ts.map +1 -1
  14. package/dist/constants.js +8 -0
  15. package/dist/constants.js.map +1 -1
  16. package/dist/context-budget.d.ts +1 -1
  17. package/dist/context-budget.d.ts.map +1 -1
  18. package/dist/context-budget.js +4 -2
  19. package/dist/context-budget.js.map +1 -1
  20. package/dist/context-compressor.d.ts +1 -1
  21. package/dist/context-compressor.d.ts.map +1 -1
  22. package/dist/context-compressor.js +5 -3
  23. package/dist/context-compressor.js.map +1 -1
  24. package/dist/context-manager.d.ts +7 -1
  25. package/dist/context-manager.d.ts.map +1 -1
  26. package/dist/context-manager.js +34 -2
  27. package/dist/context-manager.js.map +1 -1
  28. package/dist/continuation-engine.d.ts +168 -0
  29. package/dist/continuation-engine.d.ts.map +1 -0
  30. package/dist/continuation-engine.js +421 -0
  31. package/dist/continuation-engine.js.map +1 -0
  32. package/dist/cost-optimizer.d.ts +159 -0
  33. package/dist/cost-optimizer.d.ts.map +1 -0
  34. package/dist/cost-optimizer.js +406 -0
  35. package/dist/cost-optimizer.js.map +1 -0
  36. package/dist/execution-engine.d.ts.map +1 -1
  37. package/dist/execution-engine.js +9 -4
  38. package/dist/execution-engine.js.map +1 -1
  39. package/dist/execution-policy-engine.d.ts +133 -0
  40. package/dist/execution-policy-engine.d.ts.map +1 -0
  41. package/dist/execution-policy-engine.js +367 -0
  42. package/dist/execution-policy-engine.js.map +1 -0
  43. package/dist/failure-recovery.d.ts +228 -0
  44. package/dist/failure-recovery.d.ts.map +1 -0
  45. package/dist/failure-recovery.js +664 -0
  46. package/dist/failure-recovery.js.map +1 -0
  47. package/dist/hierarchical-planner.d.ts +69 -1
  48. package/dist/hierarchical-planner.d.ts.map +1 -1
  49. package/dist/hierarchical-planner.js +117 -0
  50. package/dist/hierarchical-planner.js.map +1 -1
  51. package/dist/impact-analyzer.d.ts +92 -0
  52. package/dist/impact-analyzer.d.ts.map +1 -0
  53. package/dist/impact-analyzer.js +615 -0
  54. package/dist/impact-analyzer.js.map +1 -0
  55. package/dist/index.d.ts +28 -3
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +27 -0
  58. package/dist/index.js.map +1 -1
  59. package/dist/llm-client.d.ts +1 -1
  60. package/dist/llm-client.d.ts.map +1 -1
  61. package/dist/llm-client.js +74 -7
  62. package/dist/llm-client.js.map +1 -1
  63. package/dist/memory-updater.d.ts +189 -0
  64. package/dist/memory-updater.d.ts.map +1 -0
  65. package/dist/memory-updater.js +481 -0
  66. package/dist/memory-updater.js.map +1 -0
  67. package/dist/prompt-defense.d.ts +59 -0
  68. package/dist/prompt-defense.d.ts.map +1 -0
  69. package/dist/prompt-defense.js +311 -0
  70. package/dist/prompt-defense.js.map +1 -0
  71. package/dist/reflexion.d.ts +211 -0
  72. package/dist/reflexion.d.ts.map +1 -0
  73. package/dist/reflexion.js +559 -0
  74. package/dist/reflexion.js.map +1 -0
  75. package/dist/system-prompt.d.ts +19 -3
  76. package/dist/system-prompt.d.ts.map +1 -1
  77. package/dist/system-prompt.js +203 -38
  78. package/dist/system-prompt.js.map +1 -1
  79. package/dist/task-classifier.d.ts +92 -0
  80. package/dist/task-classifier.d.ts.map +1 -0
  81. package/dist/task-classifier.js +566 -0
  82. package/dist/task-classifier.js.map +1 -0
  83. package/dist/token-budget.d.ts +131 -0
  84. package/dist/token-budget.d.ts.map +1 -0
  85. package/dist/token-budget.js +321 -0
  86. package/dist/token-budget.js.map +1 -0
  87. package/dist/types.d.ts +20 -2
  88. package/dist/types.d.ts.map +1 -1
  89. package/dist/types.js +18 -1
  90. package/dist/types.js.map +1 -1
  91. package/dist/world-state.d.ts +87 -0
  92. package/dist/world-state.d.ts.map +1 -0
  93. package/dist/world-state.js +435 -0
  94. package/dist/world-state.js.map +1 -0
  95. package/package.json +11 -21
@@ -0,0 +1,481 @@
1
+ /**
2
+ * @module memory-updater
3
+ * @description YUAN Memory Auto-Updater — 완료된 에이전트 실행에서 풍부한 학습 신호를 추출.
4
+ *
5
+ * 기존 `updateMemoryAfterRun()`은 "Task X changed N files" 수준의 기록만 남겼지만,
6
+ * MemoryUpdater는 도구 사용 패턴, 파일 공변 패턴, 성능 지표, 에러 해결 패턴,
7
+ * 코딩 규칙 자동 탐지 등을 추출하여 MemoryManager에 전달한다.
8
+ *
9
+ * 모든 메서드는 동기(synchronous) — 파일 I/O는 MemoryManager가 담당.
10
+ */
11
+ import { basename, dirname, extname } from "node:path";
12
+ // ─── Constants ───
13
+ const DEFAULT_MIN_CONFIDENCE = 0.2;
14
+ const DEFAULT_MAX_LEARNINGS = 5;
15
+ /** 에러 유형 분류를 위한 패턴 매핑 */
16
+ const ERROR_TYPE_PATTERNS = [
17
+ [/TS\d{4,5}|typescript|tsc/i, "TypeScriptError"],
18
+ [/eslint|lint/i, "LintError"],
19
+ [/ENOENT|no such file/i, "FileNotFoundError"],
20
+ [/permission denied|EACCES/i, "PermissionError"],
21
+ [/FAIL|test (failed|failure)/i, "TestFailure"],
22
+ [/syntax ?error/i, "SyntaxError"],
23
+ [/module not found|cannot find module/i, "ModuleNotFoundError"],
24
+ [/timeout|ETIMEDOUT/i, "TimeoutError"],
25
+ ];
26
+ /** 테스트 파일 패턴 */
27
+ const TEST_FILE_PATTERNS = [/\.test\.[jt]sx?$/, /\.spec\.[jt]sx?$/, /__tests__\//];
28
+ // ─── MemoryUpdater ───
29
+ /**
30
+ * MemoryUpdater — 완료된 에이전트 실행을 분석하여 학습 신호를 추출.
31
+ *
32
+ * 추출된 학습은 MemoryManager.addLearning()으로 저장할 수 있는
33
+ * `{ category, content }` 형태로 변환된다.
34
+ */
35
+ export class MemoryUpdater {
36
+ minConfidence;
37
+ maxLearningsPerRun;
38
+ shouldDetectConventions;
39
+ constructor(config) {
40
+ this.minConfidence = config?.minConfidence ?? DEFAULT_MIN_CONFIDENCE;
41
+ this.maxLearningsPerRun = config?.maxLearningsPerRun ?? DEFAULT_MAX_LEARNINGS;
42
+ this.shouldDetectConventions = config?.detectConventions ?? true;
43
+ }
44
+ /**
45
+ * 완료된 실행을 분석하여 RunAnalysis를 반환.
46
+ */
47
+ analyzeRun(params) {
48
+ const { toolResults, changedFiles, messages, tokensUsed, durationMs, iterations } = params;
49
+ const toolPatterns = this.buildToolPatterns(toolResults);
50
+ const coChangePatterns = this.detectCoChangePatterns(changedFiles);
51
+ const perfSummary = this.buildPerfSummary(toolResults, tokensUsed, durationMs, iterations);
52
+ const errorPatterns = this.extractErrorPatterns(toolResults, messages);
53
+ const conventions = this.shouldDetectConventions ? this.detectConventions(toolResults) : [];
54
+ return { toolPatterns, coChangePatterns, perfSummary, errorPatterns, conventions };
55
+ }
56
+ /**
57
+ * RunAnalysis를 MemoryManager에 저장할 학습 목록으로 변환.
58
+ * 확신도(minConfidence)를 넘는 항목만, 최대 maxLearningsPerRun개까지 반환.
59
+ */
60
+ extractLearnings(analysis, goal) {
61
+ const candidates = [];
62
+ // 도구 패턴에서 학습 추출
63
+ for (const tp of analysis.toolPatterns) {
64
+ if (tp.count >= 3 && tp.successRate < 0.5) {
65
+ candidates.push({
66
+ category: "debug",
67
+ content: `Tool "${tp.tool}" had low success rate (${(tp.successRate * 100).toFixed(0)}%) during: ${goal}`,
68
+ confidence: 0.6,
69
+ });
70
+ }
71
+ if (tp.count >= 5 && tp.successRate >= 0.9) {
72
+ candidates.push({
73
+ category: "style",
74
+ content: `Tool "${tp.tool}" is highly effective (${tp.count} calls, ${(tp.successRate * 100).toFixed(0)}% success)`,
75
+ confidence: 0.3,
76
+ });
77
+ }
78
+ }
79
+ // 에러 패턴에서 학습 추출 (해결된 것만)
80
+ for (const ep of analysis.errorPatterns) {
81
+ if (ep.resolution) {
82
+ candidates.push({
83
+ category: "debug",
84
+ content: `${ep.type}: "${truncate(ep.message, 80)}" → fix: ${ep.resolution}`,
85
+ confidence: 0.7,
86
+ });
87
+ }
88
+ }
89
+ // 공변 패턴에서 학습 추출
90
+ for (const cp of analysis.coChangePatterns) {
91
+ if (cp.frequency >= 2 || cp.files.length >= 3) {
92
+ candidates.push({
93
+ category: "style",
94
+ content: `Co-change pattern (${cp.context}): ${cp.files.map((f) => basename(f)).join(", ")}`,
95
+ confidence: 0.4,
96
+ });
97
+ }
98
+ }
99
+ // 규칙에서 학습 추출
100
+ for (const conv of analysis.conventions) {
101
+ candidates.push({
102
+ category: "style",
103
+ content: conv,
104
+ confidence: 0.5,
105
+ });
106
+ }
107
+ // 성능 관련 학습
108
+ if (analysis.perfSummary.efficiency < 0.3 && analysis.perfSummary.iterations > 5) {
109
+ candidates.push({
110
+ category: "build",
111
+ content: `Low efficiency run (${(analysis.perfSummary.efficiency * 100).toFixed(0)}%) for: ${truncate(goal, 60)} — consider breaking into smaller tasks`,
112
+ confidence: 0.5,
113
+ });
114
+ }
115
+ // 확신도 필터 → 정렬 → 상위 N개
116
+ return candidates
117
+ .filter((c) => c.confidence >= this.minConfidence)
118
+ .sort((a, b) => b.confidence - a.confidence)
119
+ .slice(0, this.maxLearningsPerRun)
120
+ .map(({ category, content }) => ({ category, content }));
121
+ }
122
+ /**
123
+ * 도구 실행 결과에서 코딩 규칙을 자동 탐지.
124
+ *
125
+ * - file_read 출력: 들여쓰기 스타일 (탭 vs 공백, 2칸 vs 4칸)
126
+ * - file_write/file_edit 출력: 네이밍 규칙 (camelCase, snake_case)
127
+ * - shell_exec 출력: 테스트 프레임워크, 빌드 도구
128
+ * - 성공 패턴: "항상 읽기 후 쓰기", "변경 후 테스트 실행"
129
+ */
130
+ detectConventions(toolResults) {
131
+ const conventions = [];
132
+ const seenConventions = new Set();
133
+ const addConvention = (conv) => {
134
+ if (!seenConventions.has(conv)) {
135
+ seenConventions.add(conv);
136
+ conventions.push(conv);
137
+ }
138
+ };
139
+ // 들여쓰기 스타일 감지 (file_read 출력에서)
140
+ const readOutputs = toolResults
141
+ .filter((r) => r.name === "file_read" && r.success && r.output.length > 50)
142
+ .map((r) => r.output);
143
+ if (readOutputs.length > 0) {
144
+ const indentStyle = this.detectIndentStyle(readOutputs);
145
+ if (indentStyle)
146
+ addConvention(indentStyle);
147
+ }
148
+ // 네이밍 규칙 감지 (file_write/file_edit 출력에서)
149
+ const writeOutputs = toolResults
150
+ .filter((r) => (r.name === "file_write" || r.name === "file_edit") && r.success)
151
+ .map((r) => r.output);
152
+ if (writeOutputs.length > 0) {
153
+ const namingStyle = this.detectNamingConvention(writeOutputs);
154
+ if (namingStyle)
155
+ addConvention(namingStyle);
156
+ }
157
+ // 테스트/빌드 도구 감지 (shell_exec 출력에서)
158
+ const shellOutputs = toolResults
159
+ .filter((r) => r.name === "shell_exec" && r.success)
160
+ .map((r) => r.output);
161
+ for (const output of shellOutputs) {
162
+ if (/jest/i.test(output))
163
+ addConvention("Test framework: Jest");
164
+ if (/vitest/i.test(output))
165
+ addConvention("Test framework: Vitest");
166
+ if (/mocha/i.test(output))
167
+ addConvention("Test framework: Mocha");
168
+ if (/next build|next dev/i.test(output))
169
+ addConvention("Build tool: Next.js");
170
+ if (/vite build/i.test(output))
171
+ addConvention("Build tool: Vite");
172
+ if (/tsc --noEmit/i.test(output))
173
+ addConvention("Type checking: tsc --noEmit");
174
+ }
175
+ // 워크플로우 패턴 감지 — "항상 읽고 쓰기" 등
176
+ const toolSequence = toolResults.map((r) => r.name);
177
+ if (this.detectReadBeforeWrite(toolSequence)) {
178
+ addConvention("Workflow: always read file before writing");
179
+ }
180
+ if (this.detectTestAfterChange(toolSequence)) {
181
+ addConvention("Workflow: run tests after code changes");
182
+ }
183
+ return conventions;
184
+ }
185
+ /**
186
+ * 에러 패턴과 해결 방법 추출.
187
+ * 실패한 도구 호출 → 이후 메시지에서 수정 시도 탐지.
188
+ */
189
+ extractErrorPatterns(toolResults, messages) {
190
+ const errorMap = new Map();
191
+ for (let i = 0; i < toolResults.length; i++) {
192
+ const result = toolResults[i];
193
+ if (result.success)
194
+ continue;
195
+ const errorType = this.classifyErrorType(result.output);
196
+ const errorMsg = this.extractErrorMessage(result.output);
197
+ const key = `${errorType}:${truncate(errorMsg, 60)}`;
198
+ if (errorMap.has(key)) {
199
+ errorMap.get(key).frequency++;
200
+ continue;
201
+ }
202
+ // 후속 메시지에서 해결 시도 탐색
203
+ const resolution = this.findResolution(result, toolResults, i, messages);
204
+ errorMap.set(key, {
205
+ type: errorType,
206
+ message: errorMsg,
207
+ tool: result.name,
208
+ resolution,
209
+ frequency: 1,
210
+ });
211
+ }
212
+ return Array.from(errorMap.values());
213
+ }
214
+ /**
215
+ * 변경된 파일 목록에서 공변 패턴을 감지.
216
+ *
217
+ * - 같은 디렉토리의 파일 그룹
218
+ * - test + implementation 쌍
219
+ * - types + implementation 쌍
220
+ * - index.ts (배럴 파일) 패턴
221
+ */
222
+ detectCoChangePatterns(changedFiles) {
223
+ if (changedFiles.length < 2)
224
+ return [];
225
+ const patterns = [];
226
+ // 테스트 + 구현 파일 쌍 탐지
227
+ const testPairs = this.findTestImplementationPairs(changedFiles);
228
+ for (const pair of testPairs) {
229
+ patterns.push({
230
+ files: pair,
231
+ frequency: 1,
232
+ context: "test + implementation",
233
+ });
234
+ }
235
+ // 타입 + 구현 파일 쌍 탐지
236
+ const typePairs = this.findTypeImplementationPairs(changedFiles);
237
+ for (const pair of typePairs) {
238
+ patterns.push({
239
+ files: pair,
240
+ frequency: 1,
241
+ context: "types + implementation",
242
+ });
243
+ }
244
+ // 같은 디렉토리 내 파일 그룹 (3개 이상)
245
+ const dirGroups = this.groupByDirectory(changedFiles);
246
+ for (const [dir, files] of dirGroups) {
247
+ if (files.length >= 3) {
248
+ patterns.push({
249
+ files,
250
+ frequency: 1,
251
+ context: `directory group: ${dir}`,
252
+ });
253
+ }
254
+ }
255
+ // index.ts 배럴 파일 포함 시
256
+ const indexFiles = changedFiles.filter((f) => basename(f) === "index.ts" || basename(f) === "index.js");
257
+ if (indexFiles.length > 0) {
258
+ const nonIndex = changedFiles.filter((f) => !indexFiles.includes(f));
259
+ if (nonIndex.length > 0) {
260
+ patterns.push({
261
+ files: [...indexFiles, ...nonIndex.slice(0, 3)],
262
+ frequency: 1,
263
+ context: "barrel export update with new modules",
264
+ });
265
+ }
266
+ }
267
+ return patterns;
268
+ }
269
+ // ─── Private helpers ───
270
+ /** 도구별 사용 패턴 집계 */
271
+ buildToolPatterns(toolResults) {
272
+ const map = new Map();
273
+ for (const r of toolResults) {
274
+ const entry = map.get(r.name) ?? { count: 0, successes: 0, totalDuration: 0 };
275
+ entry.count++;
276
+ if (r.success)
277
+ entry.successes++;
278
+ entry.totalDuration += r.durationMs ?? 0;
279
+ map.set(r.name, entry);
280
+ }
281
+ return Array.from(map.entries()).map(([tool, stats]) => ({
282
+ tool,
283
+ count: stats.count,
284
+ successRate: stats.count > 0 ? stats.successes / stats.count : 0,
285
+ avgDurationMs: stats.count > 0 ? Math.round(stats.totalDuration / stats.count) : 0,
286
+ }));
287
+ }
288
+ /** 성능 요약 생성 */
289
+ buildPerfSummary(toolResults, tokensUsed, durationMs, iterations) {
290
+ const successfulTools = toolResults.filter((r) => r.success).length;
291
+ // 효율성: 성공한 도구 호출 비율 (실패가 많으면 비효율)
292
+ const efficiency = toolResults.length > 0 ? successfulTools / toolResults.length : 1;
293
+ return {
294
+ iterations,
295
+ totalTokens: tokensUsed,
296
+ tokensPerIteration: iterations > 0 ? Math.round(tokensUsed / iterations) : 0,
297
+ durationMs,
298
+ efficiency: Math.round(efficiency * 100) / 100,
299
+ };
300
+ }
301
+ /** 에러 유형 분류 */
302
+ classifyErrorType(output) {
303
+ for (const [pattern, type] of ERROR_TYPE_PATTERNS) {
304
+ if (pattern.test(output))
305
+ return type;
306
+ }
307
+ return "UnknownError";
308
+ }
309
+ /** 에러 메시지 첫 줄 추출 */
310
+ extractErrorMessage(output) {
311
+ const lines = output.split("\n").filter((l) => l.trim().length > 0);
312
+ // "error" 키워드가 포함된 첫 줄 우선
313
+ const errorLine = lines.find((l) => /error/i.test(l));
314
+ return truncate(errorLine ?? lines[0] ?? "Unknown error", 120);
315
+ }
316
+ /**
317
+ * 실패한 도구 호출 이후 해결 시도를 탐색.
318
+ * 같은 도구가 이후에 성공했으면 그 출력의 일부를 해결 방법으로 추출.
319
+ */
320
+ findResolution(failedResult, allResults, failedIndex, messages) {
321
+ // 후속 5개 도구 결과 내에서 같은 도구 성공 탐색
322
+ const lookAhead = Math.min(failedIndex + 6, allResults.length);
323
+ for (let j = failedIndex + 1; j < lookAhead; j++) {
324
+ const subsequent = allResults[j];
325
+ if (subsequent.name === failedResult.name && subsequent.success) {
326
+ return `Retried "${subsequent.name}" successfully`;
327
+ }
328
+ // file_edit로 수정한 경우
329
+ if (subsequent.name === "file_edit" && subsequent.success) {
330
+ return "Fixed via file edit";
331
+ }
332
+ }
333
+ // 어시스턴트 메시지에서 "fix", "resolved", "수정" 키워드 탐색
334
+ for (const msg of messages) {
335
+ if (msg.role !== "assistant" || !msg.content)
336
+ continue;
337
+ const content = msg.content;
338
+ if (/(?:fix(?:ed)?|resolv(?:ed|ing)|수정|해결)/i.test(content)) {
339
+ // 해결 관련 메시지의 첫 문장 추출
340
+ const sentence = content.split(/[.!\n]/)[0];
341
+ if (sentence && sentence.length > 10) {
342
+ return truncate(sentence.trim(), 100);
343
+ }
344
+ }
345
+ }
346
+ return null;
347
+ }
348
+ /** 들여쓰기 스타일 감지 — 탭 vs 공백, 2칸 vs 4칸 */
349
+ detectIndentStyle(fileContents) {
350
+ let tabs = 0;
351
+ let spaces2 = 0;
352
+ let spaces4 = 0;
353
+ for (const content of fileContents) {
354
+ const lines = content.split("\n").slice(0, 100); // 상위 100줄만 검사
355
+ for (const line of lines) {
356
+ if (line.startsWith("\t"))
357
+ tabs++;
358
+ else if (line.startsWith(" "))
359
+ spaces4++;
360
+ else if (line.startsWith(" ") && !line.startsWith(" "))
361
+ spaces2++;
362
+ }
363
+ }
364
+ const total = tabs + spaces2 + spaces4;
365
+ if (total < 5)
366
+ return null; // 표본 부족
367
+ if (tabs > total * 0.6)
368
+ return "Indent style: tabs";
369
+ if (spaces2 > total * 0.6)
370
+ return "Indent style: 2 spaces";
371
+ if (spaces4 > total * 0.6)
372
+ return "Indent style: 4 spaces";
373
+ return null;
374
+ }
375
+ /** 네이밍 규칙 감지 — camelCase vs snake_case */
376
+ detectNamingConvention(writeOutputs) {
377
+ let camelCase = 0;
378
+ let snakeCase = 0;
379
+ // 함수/변수 선언 패턴 매칭
380
+ const camelPattern = /(?:const|let|var|function)\s+[a-z][a-zA-Z0-9]*[A-Z]/g;
381
+ const snakePattern = /(?:const|let|var|function)\s+[a-z]+_[a-z]/g;
382
+ for (const output of writeOutputs) {
383
+ camelCase += (output.match(camelPattern) ?? []).length;
384
+ snakeCase += (output.match(snakePattern) ?? []).length;
385
+ }
386
+ const total = camelCase + snakeCase;
387
+ if (total < 3)
388
+ return null;
389
+ if (camelCase > total * 0.7)
390
+ return "Naming convention: camelCase";
391
+ if (snakeCase > total * 0.7)
392
+ return "Naming convention: snake_case";
393
+ return null;
394
+ }
395
+ /** "읽기 후 쓰기" 패턴 감지 */
396
+ detectReadBeforeWrite(toolSequence) {
397
+ let readThenWrite = 0;
398
+ let writeWithoutRead = 0;
399
+ for (let i = 0; i < toolSequence.length; i++) {
400
+ if (toolSequence[i] === "file_write" || toolSequence[i] === "file_edit") {
401
+ // 직전 3개 이내에 file_read가 있는지 확인
402
+ const lookBack = toolSequence.slice(Math.max(0, i - 3), i);
403
+ if (lookBack.includes("file_read")) {
404
+ readThenWrite++;
405
+ }
406
+ else {
407
+ writeWithoutRead++;
408
+ }
409
+ }
410
+ }
411
+ const total = readThenWrite + writeWithoutRead;
412
+ return total >= 3 && readThenWrite > total * 0.7;
413
+ }
414
+ /** "변경 후 테스트" 패턴 감지 */
415
+ detectTestAfterChange(toolSequence) {
416
+ let changesThenTest = 0;
417
+ for (let i = 0; i < toolSequence.length; i++) {
418
+ if (toolSequence[i] === "shell_exec") {
419
+ // 직전에 file_write/file_edit가 있었는지 확인
420
+ const lookBack = toolSequence.slice(Math.max(0, i - 5), i);
421
+ if (lookBack.some((t) => t === "file_write" || t === "file_edit")) {
422
+ changesThenTest++;
423
+ }
424
+ }
425
+ }
426
+ return changesThenTest >= 2;
427
+ }
428
+ /** 테스트 + 구현 파일 쌍 찾기 */
429
+ findTestImplementationPairs(files) {
430
+ const pairs = [];
431
+ const testFiles = files.filter((f) => TEST_FILE_PATTERNS.some((p) => p.test(f)));
432
+ const implFiles = files.filter((f) => !TEST_FILE_PATTERNS.some((p) => p.test(f)));
433
+ for (const testFile of testFiles) {
434
+ const testBase = basename(testFile)
435
+ .replace(/\.test\.[jt]sx?$/, "")
436
+ .replace(/\.spec\.[jt]sx?$/, "");
437
+ const matchingImpl = implFiles.find((f) => {
438
+ const implBase = basename(f).replace(extname(f), "");
439
+ return implBase === testBase && dirname(f) === dirname(testFile).replace(/__tests__\/?/, "");
440
+ });
441
+ if (matchingImpl) {
442
+ pairs.push([matchingImpl, testFile]);
443
+ }
444
+ }
445
+ return pairs;
446
+ }
447
+ /** 타입 파일 + 구현 파일 쌍 찾기 */
448
+ findTypeImplementationPairs(files) {
449
+ const pairs = [];
450
+ const typeFiles = files.filter((f) => basename(f).includes("types") || basename(f).includes(".d.ts"));
451
+ const implFiles = files.filter((f) => !basename(f).includes("types") && !basename(f).endsWith(".d.ts"));
452
+ for (const typeFile of typeFiles) {
453
+ // 같은 디렉토리의 구현 파일과 매칭
454
+ const typeDir = dirname(typeFile);
455
+ const sameDir = implFiles.filter((f) => dirname(f) === typeDir);
456
+ if (sameDir.length > 0) {
457
+ pairs.push([typeFile, ...sameDir.slice(0, 2)]);
458
+ }
459
+ }
460
+ return pairs;
461
+ }
462
+ /** 파일을 디렉토리별로 그룹화 */
463
+ groupByDirectory(files) {
464
+ const groups = new Map();
465
+ for (const file of files) {
466
+ const dir = dirname(file);
467
+ const group = groups.get(dir) ?? [];
468
+ group.push(file);
469
+ groups.set(dir, group);
470
+ }
471
+ return groups;
472
+ }
473
+ }
474
+ // ─── Utility ───
475
+ /** 문자열을 maxLen으로 자르고 말줄임 */
476
+ function truncate(str, maxLen) {
477
+ if (str.length <= maxLen)
478
+ return str;
479
+ return str.slice(0, maxLen - 1) + "…";
480
+ }
481
+ //# sourceMappingURL=memory-updater.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-updater.js","sourceRoot":"","sources":["../src/memory-updater.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Prompt Injection Defense Module
3
+ *
4
+ * Sanitizes tool outputs and user inputs to prevent prompt injection attacks.
5
+ * Standalone module — no internal imports.
6
+ */
7
+ export interface SanitizeResult {
8
+ output: string;
9
+ injectionDetected: boolean;
10
+ patternsFound: string[];
11
+ truncated: boolean;
12
+ originalLength: number;
13
+ }
14
+ export interface ValidationResult {
15
+ valid: boolean;
16
+ injectionDetected: boolean;
17
+ severity: InjectionSeverity;
18
+ patternsFound: string[];
19
+ sanitizedInput: string;
20
+ }
21
+ export type InjectionSeverity = "none" | "low" | "medium" | "high" | "critical";
22
+ export interface InjectionMatch {
23
+ pattern: string;
24
+ match: string;
25
+ position: number;
26
+ }
27
+ export interface InjectionDetection {
28
+ detected: boolean;
29
+ severity: InjectionSeverity;
30
+ patterns: InjectionMatch[];
31
+ recommendation: "allow" | "sanitize" | "block";
32
+ }
33
+ export type StrictnessLevel = "low" | "medium" | "high";
34
+ export declare class PromptDefense {
35
+ private readonly defaultLevel;
36
+ constructor(defaultLevel?: StrictnessLevel);
37
+ /**
38
+ * Detect injection patterns in text, including base64-encoded variants.
39
+ */
40
+ detectInjection(text: string): InjectionDetection;
41
+ /**
42
+ * Sanitize a string: strip injection patterns, optionally truncate and filter.
43
+ */
44
+ sanitize(text: string, level?: StrictnessLevel): string;
45
+ /**
46
+ * Sanitize tool output: detect injections, strip patterns, truncate to limit.
47
+ */
48
+ sanitizeToolOutput(toolName: string, output: string): SanitizeResult;
49
+ /**
50
+ * Validate user input for injection attempts.
51
+ */
52
+ validateUserInput(input: string): ValidationResult;
53
+ /**
54
+ * Wrap tool output with safety markers to prevent the LLM from confusing
55
+ * tool output with its own instructions.
56
+ */
57
+ wrapToolOutput(toolName: string, output: string): string;
58
+ }
59
+ //# sourceMappingURL=prompt-defense.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-defense.d.ts","sourceRoot":"","sources":["../src/prompt-defense.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAEhF,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,cAAc,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;CAChD;AAED,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAiMxD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkB;gBAEnC,YAAY,GAAE,eAA0B;IAIpD;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB;IAkCjD;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,MAAM;IAsDvD;;OAEG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc;IA0BpE;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB;IAalD;;;OAGG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;CAIzD"}