aiexecode 1.0.96 → 1.0.98

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.

Potentially problematic release.


This version of aiexecode might be problematic. Click here for more details.

@@ -0,0 +1,132 @@
1
+ /**
2
+ * File Reference Parser
3
+ *
4
+ * 메시지에서 @경로 형태의 파일/디렉토리 참조를 파싱하고 변환합니다.
5
+ */
6
+
7
+ import { resolve } from 'path';
8
+ import { safeStat, safeExists } from './safe_fs.js';
9
+
10
+ /**
11
+ * 메시지에서 @참조를 파싱하여 파일/디렉토리 목록과 변환된 메시지를 반환합니다.
12
+ *
13
+ * @param {string} message - 사용자 입력 메시지
14
+ * @returns {Promise<Object>} 파싱 결과
15
+ * @example
16
+ * // 입력: "@src/index.js @package.json 분석해줘"
17
+ * // 출력: {
18
+ * // hasReferences: true,
19
+ * // files: ['src/index.js', 'package.json'],
20
+ * // directories: [],
21
+ * // transformedMessage: "참조된 파일:\n- src/index.js (파일)\n- package.json (파일)\n\n분석해줘"
22
+ * // }
23
+ */
24
+ export async function parseFileReferences(message) {
25
+ if (!message || typeof message !== 'string') {
26
+ return {
27
+ hasReferences: false,
28
+ files: [],
29
+ directories: [],
30
+ transformedMessage: message || ''
31
+ };
32
+ }
33
+
34
+ // @ 뒤에 경로 문자열이 오는 패턴 매칭
35
+ // 경로: 알파벳, 숫자, /, ., _, -, ~로 구성
36
+ const atPattern = /@([^\s@]+)/g;
37
+ const matches = [...message.matchAll(atPattern)];
38
+
39
+ if (matches.length === 0) {
40
+ return {
41
+ hasReferences: false,
42
+ files: [],
43
+ directories: [],
44
+ transformedMessage: message
45
+ };
46
+ }
47
+
48
+ const files = [];
49
+ const directories = [];
50
+ const validReferences = [];
51
+
52
+ // 각 @참조 검증
53
+ for (const match of matches) {
54
+ const refPath = match[1];
55
+
56
+ // 경로 유효성 검사 (최소한의 검증)
57
+ if (!refPath || refPath.length === 0) {
58
+ continue;
59
+ }
60
+
61
+ // 절대 경로로 변환
62
+ const absolutePath = resolve(process.cwd(), refPath);
63
+
64
+ try {
65
+ const exists = await safeExists(absolutePath);
66
+ if (!exists) {
67
+ continue;
68
+ }
69
+
70
+ const stat = await safeStat(absolutePath);
71
+
72
+ if (stat.isDirectory()) {
73
+ directories.push(refPath);
74
+ validReferences.push({
75
+ original: match[0],
76
+ path: refPath,
77
+ type: 'directory'
78
+ });
79
+ } else if (stat.isFile()) {
80
+ files.push(refPath);
81
+ validReferences.push({
82
+ original: match[0],
83
+ path: refPath,
84
+ type: 'file'
85
+ });
86
+ }
87
+ } catch (error) {
88
+ // 존재하지 않거나 접근 불가능한 경로는 무시
89
+ continue;
90
+ }
91
+ }
92
+
93
+ // 유효한 참조가 없으면 원본 메시지 반환
94
+ if (validReferences.length === 0) {
95
+ return {
96
+ hasReferences: false,
97
+ files: [],
98
+ directories: [],
99
+ transformedMessage: message
100
+ };
101
+ }
102
+
103
+ // 메시지에서 @참조 제거
104
+ let cleanedMessage = message;
105
+ for (const ref of validReferences) {
106
+ cleanedMessage = cleanedMessage.replace(ref.original, '').trim();
107
+ }
108
+
109
+ // 연속된 공백 정리
110
+ cleanedMessage = cleanedMessage.replace(/\s+/g, ' ').trim();
111
+
112
+ // 변환된 메시지 생성
113
+ const referenceLines = validReferences.map(ref => {
114
+ const suffix = ref.type === 'directory' ? '/' : '';
115
+ const typeLabel = ref.type === 'directory' ? '디렉토리' : '파일';
116
+ return `- ${ref.path}${suffix} (${typeLabel})`;
117
+ });
118
+
119
+ const transformedMessage = [
120
+ '참조된 파일:',
121
+ ...referenceLines,
122
+ '',
123
+ cleanedMessage
124
+ ].join('\n');
125
+
126
+ return {
127
+ hasReferences: true,
128
+ files,
129
+ directories,
130
+ transformedMessage
131
+ };
132
+ }