@ksm0709/context 0.0.21 → 0.0.23
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/README.md +4 -0
- package/dist/cli/index.js +8 -116
- package/dist/index.js +65 -1227
- package/dist/mcp.js +33061 -0
- package/dist/omx/index.mjs +53 -352
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -1,838 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// src/index.ts
|
|
3
|
-
import { existsSync as
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
// node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
7
|
-
function createScanner(text, ignoreTrivia = false) {
|
|
8
|
-
const len = text.length;
|
|
9
|
-
let pos = 0, value = "", tokenOffset = 0, token = 16, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0;
|
|
10
|
-
function scanHexDigits(count, exact) {
|
|
11
|
-
let digits = 0;
|
|
12
|
-
let value2 = 0;
|
|
13
|
-
while (digits < count || !exact) {
|
|
14
|
-
let ch = text.charCodeAt(pos);
|
|
15
|
-
if (ch >= 48 && ch <= 57) {
|
|
16
|
-
value2 = value2 * 16 + ch - 48;
|
|
17
|
-
} else if (ch >= 65 && ch <= 70) {
|
|
18
|
-
value2 = value2 * 16 + ch - 65 + 10;
|
|
19
|
-
} else if (ch >= 97 && ch <= 102) {
|
|
20
|
-
value2 = value2 * 16 + ch - 97 + 10;
|
|
21
|
-
} else {
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
pos++;
|
|
25
|
-
digits++;
|
|
26
|
-
}
|
|
27
|
-
if (digits < count) {
|
|
28
|
-
value2 = -1;
|
|
29
|
-
}
|
|
30
|
-
return value2;
|
|
31
|
-
}
|
|
32
|
-
function setPosition(newPosition) {
|
|
33
|
-
pos = newPosition;
|
|
34
|
-
value = "";
|
|
35
|
-
tokenOffset = 0;
|
|
36
|
-
token = 16;
|
|
37
|
-
scanError = 0;
|
|
38
|
-
}
|
|
39
|
-
function scanNumber() {
|
|
40
|
-
let start = pos;
|
|
41
|
-
if (text.charCodeAt(pos) === 48) {
|
|
42
|
-
pos++;
|
|
43
|
-
} else {
|
|
44
|
-
pos++;
|
|
45
|
-
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
46
|
-
pos++;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
if (pos < text.length && text.charCodeAt(pos) === 46) {
|
|
50
|
-
pos++;
|
|
51
|
-
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
52
|
-
pos++;
|
|
53
|
-
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
54
|
-
pos++;
|
|
55
|
-
}
|
|
56
|
-
} else {
|
|
57
|
-
scanError = 3;
|
|
58
|
-
return text.substring(start, pos);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
let end = pos;
|
|
62
|
-
if (pos < text.length && (text.charCodeAt(pos) === 69 || text.charCodeAt(pos) === 101)) {
|
|
63
|
-
pos++;
|
|
64
|
-
if (pos < text.length && text.charCodeAt(pos) === 43 || text.charCodeAt(pos) === 45) {
|
|
65
|
-
pos++;
|
|
66
|
-
}
|
|
67
|
-
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
68
|
-
pos++;
|
|
69
|
-
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
70
|
-
pos++;
|
|
71
|
-
}
|
|
72
|
-
end = pos;
|
|
73
|
-
} else {
|
|
74
|
-
scanError = 3;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return text.substring(start, end);
|
|
78
|
-
}
|
|
79
|
-
function scanString() {
|
|
80
|
-
let result = "", start = pos;
|
|
81
|
-
while (true) {
|
|
82
|
-
if (pos >= len) {
|
|
83
|
-
result += text.substring(start, pos);
|
|
84
|
-
scanError = 2;
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
const ch = text.charCodeAt(pos);
|
|
88
|
-
if (ch === 34) {
|
|
89
|
-
result += text.substring(start, pos);
|
|
90
|
-
pos++;
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
if (ch === 92) {
|
|
94
|
-
result += text.substring(start, pos);
|
|
95
|
-
pos++;
|
|
96
|
-
if (pos >= len) {
|
|
97
|
-
scanError = 2;
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
const ch2 = text.charCodeAt(pos++);
|
|
101
|
-
switch (ch2) {
|
|
102
|
-
case 34:
|
|
103
|
-
result += '"';
|
|
104
|
-
break;
|
|
105
|
-
case 92:
|
|
106
|
-
result += "\\";
|
|
107
|
-
break;
|
|
108
|
-
case 47:
|
|
109
|
-
result += "/";
|
|
110
|
-
break;
|
|
111
|
-
case 98:
|
|
112
|
-
result += "\b";
|
|
113
|
-
break;
|
|
114
|
-
case 102:
|
|
115
|
-
result += "\f";
|
|
116
|
-
break;
|
|
117
|
-
case 110:
|
|
118
|
-
result += `
|
|
119
|
-
`;
|
|
120
|
-
break;
|
|
121
|
-
case 114:
|
|
122
|
-
result += "\r";
|
|
123
|
-
break;
|
|
124
|
-
case 116:
|
|
125
|
-
result += "\t";
|
|
126
|
-
break;
|
|
127
|
-
case 117:
|
|
128
|
-
const ch3 = scanHexDigits(4, true);
|
|
129
|
-
if (ch3 >= 0) {
|
|
130
|
-
result += String.fromCharCode(ch3);
|
|
131
|
-
} else {
|
|
132
|
-
scanError = 4;
|
|
133
|
-
}
|
|
134
|
-
break;
|
|
135
|
-
default:
|
|
136
|
-
scanError = 5;
|
|
137
|
-
}
|
|
138
|
-
start = pos;
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
if (ch >= 0 && ch <= 31) {
|
|
142
|
-
if (isLineBreak(ch)) {
|
|
143
|
-
result += text.substring(start, pos);
|
|
144
|
-
scanError = 2;
|
|
145
|
-
break;
|
|
146
|
-
} else {
|
|
147
|
-
scanError = 6;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
pos++;
|
|
151
|
-
}
|
|
152
|
-
return result;
|
|
153
|
-
}
|
|
154
|
-
function scanNext() {
|
|
155
|
-
value = "";
|
|
156
|
-
scanError = 0;
|
|
157
|
-
tokenOffset = pos;
|
|
158
|
-
lineStartOffset = lineNumber;
|
|
159
|
-
prevTokenLineStartOffset = tokenLineStartOffset;
|
|
160
|
-
if (pos >= len) {
|
|
161
|
-
tokenOffset = len;
|
|
162
|
-
return token = 17;
|
|
163
|
-
}
|
|
164
|
-
let code = text.charCodeAt(pos);
|
|
165
|
-
if (isWhiteSpace(code)) {
|
|
166
|
-
do {
|
|
167
|
-
pos++;
|
|
168
|
-
value += String.fromCharCode(code);
|
|
169
|
-
code = text.charCodeAt(pos);
|
|
170
|
-
} while (isWhiteSpace(code));
|
|
171
|
-
return token = 15;
|
|
172
|
-
}
|
|
173
|
-
if (isLineBreak(code)) {
|
|
174
|
-
pos++;
|
|
175
|
-
value += String.fromCharCode(code);
|
|
176
|
-
if (code === 13 && text.charCodeAt(pos) === 10) {
|
|
177
|
-
pos++;
|
|
178
|
-
value += `
|
|
179
|
-
`;
|
|
180
|
-
}
|
|
181
|
-
lineNumber++;
|
|
182
|
-
tokenLineStartOffset = pos;
|
|
183
|
-
return token = 14;
|
|
184
|
-
}
|
|
185
|
-
switch (code) {
|
|
186
|
-
case 123:
|
|
187
|
-
pos++;
|
|
188
|
-
return token = 1;
|
|
189
|
-
case 125:
|
|
190
|
-
pos++;
|
|
191
|
-
return token = 2;
|
|
192
|
-
case 91:
|
|
193
|
-
pos++;
|
|
194
|
-
return token = 3;
|
|
195
|
-
case 93:
|
|
196
|
-
pos++;
|
|
197
|
-
return token = 4;
|
|
198
|
-
case 58:
|
|
199
|
-
pos++;
|
|
200
|
-
return token = 6;
|
|
201
|
-
case 44:
|
|
202
|
-
pos++;
|
|
203
|
-
return token = 5;
|
|
204
|
-
case 34:
|
|
205
|
-
pos++;
|
|
206
|
-
value = scanString();
|
|
207
|
-
return token = 10;
|
|
208
|
-
case 47:
|
|
209
|
-
const start = pos - 1;
|
|
210
|
-
if (text.charCodeAt(pos + 1) === 47) {
|
|
211
|
-
pos += 2;
|
|
212
|
-
while (pos < len) {
|
|
213
|
-
if (isLineBreak(text.charCodeAt(pos))) {
|
|
214
|
-
break;
|
|
215
|
-
}
|
|
216
|
-
pos++;
|
|
217
|
-
}
|
|
218
|
-
value = text.substring(start, pos);
|
|
219
|
-
return token = 12;
|
|
220
|
-
}
|
|
221
|
-
if (text.charCodeAt(pos + 1) === 42) {
|
|
222
|
-
pos += 2;
|
|
223
|
-
const safeLength = len - 1;
|
|
224
|
-
let commentClosed = false;
|
|
225
|
-
while (pos < safeLength) {
|
|
226
|
-
const ch = text.charCodeAt(pos);
|
|
227
|
-
if (ch === 42 && text.charCodeAt(pos + 1) === 47) {
|
|
228
|
-
pos += 2;
|
|
229
|
-
commentClosed = true;
|
|
230
|
-
break;
|
|
231
|
-
}
|
|
232
|
-
pos++;
|
|
233
|
-
if (isLineBreak(ch)) {
|
|
234
|
-
if (ch === 13 && text.charCodeAt(pos) === 10) {
|
|
235
|
-
pos++;
|
|
236
|
-
}
|
|
237
|
-
lineNumber++;
|
|
238
|
-
tokenLineStartOffset = pos;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
if (!commentClosed) {
|
|
242
|
-
pos++;
|
|
243
|
-
scanError = 1;
|
|
244
|
-
}
|
|
245
|
-
value = text.substring(start, pos);
|
|
246
|
-
return token = 13;
|
|
247
|
-
}
|
|
248
|
-
value += String.fromCharCode(code);
|
|
249
|
-
pos++;
|
|
250
|
-
return token = 16;
|
|
251
|
-
case 45:
|
|
252
|
-
value += String.fromCharCode(code);
|
|
253
|
-
pos++;
|
|
254
|
-
if (pos === len || !isDigit(text.charCodeAt(pos))) {
|
|
255
|
-
return token = 16;
|
|
256
|
-
}
|
|
257
|
-
case 48:
|
|
258
|
-
case 49:
|
|
259
|
-
case 50:
|
|
260
|
-
case 51:
|
|
261
|
-
case 52:
|
|
262
|
-
case 53:
|
|
263
|
-
case 54:
|
|
264
|
-
case 55:
|
|
265
|
-
case 56:
|
|
266
|
-
case 57:
|
|
267
|
-
value += scanNumber();
|
|
268
|
-
return token = 11;
|
|
269
|
-
default:
|
|
270
|
-
while (pos < len && isUnknownContentCharacter(code)) {
|
|
271
|
-
pos++;
|
|
272
|
-
code = text.charCodeAt(pos);
|
|
273
|
-
}
|
|
274
|
-
if (tokenOffset !== pos) {
|
|
275
|
-
value = text.substring(tokenOffset, pos);
|
|
276
|
-
switch (value) {
|
|
277
|
-
case "true":
|
|
278
|
-
return token = 8;
|
|
279
|
-
case "false":
|
|
280
|
-
return token = 9;
|
|
281
|
-
case "null":
|
|
282
|
-
return token = 7;
|
|
283
|
-
}
|
|
284
|
-
return token = 16;
|
|
285
|
-
}
|
|
286
|
-
value += String.fromCharCode(code);
|
|
287
|
-
pos++;
|
|
288
|
-
return token = 16;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
function isUnknownContentCharacter(code) {
|
|
292
|
-
if (isWhiteSpace(code) || isLineBreak(code)) {
|
|
293
|
-
return false;
|
|
294
|
-
}
|
|
295
|
-
switch (code) {
|
|
296
|
-
case 125:
|
|
297
|
-
case 93:
|
|
298
|
-
case 123:
|
|
299
|
-
case 91:
|
|
300
|
-
case 34:
|
|
301
|
-
case 58:
|
|
302
|
-
case 44:
|
|
303
|
-
case 47:
|
|
304
|
-
return false;
|
|
305
|
-
}
|
|
306
|
-
return true;
|
|
307
|
-
}
|
|
308
|
-
function scanNextNonTrivia() {
|
|
309
|
-
let result;
|
|
310
|
-
do {
|
|
311
|
-
result = scanNext();
|
|
312
|
-
} while (result >= 12 && result <= 15);
|
|
313
|
-
return result;
|
|
314
|
-
}
|
|
315
|
-
return {
|
|
316
|
-
setPosition,
|
|
317
|
-
getPosition: () => pos,
|
|
318
|
-
scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
|
|
319
|
-
getToken: () => token,
|
|
320
|
-
getTokenValue: () => value,
|
|
321
|
-
getTokenOffset: () => tokenOffset,
|
|
322
|
-
getTokenLength: () => pos - tokenOffset,
|
|
323
|
-
getTokenStartLine: () => lineStartOffset,
|
|
324
|
-
getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,
|
|
325
|
-
getTokenError: () => scanError
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
function isWhiteSpace(ch) {
|
|
329
|
-
return ch === 32 || ch === 9;
|
|
330
|
-
}
|
|
331
|
-
function isLineBreak(ch) {
|
|
332
|
-
return ch === 10 || ch === 13;
|
|
333
|
-
}
|
|
334
|
-
function isDigit(ch) {
|
|
335
|
-
return ch >= 48 && ch <= 57;
|
|
336
|
-
}
|
|
337
|
-
var CharacterCodes;
|
|
338
|
-
(function(CharacterCodes2) {
|
|
339
|
-
CharacterCodes2[CharacterCodes2["lineFeed"] = 10] = "lineFeed";
|
|
340
|
-
CharacterCodes2[CharacterCodes2["carriageReturn"] = 13] = "carriageReturn";
|
|
341
|
-
CharacterCodes2[CharacterCodes2["space"] = 32] = "space";
|
|
342
|
-
CharacterCodes2[CharacterCodes2["_0"] = 48] = "_0";
|
|
343
|
-
CharacterCodes2[CharacterCodes2["_1"] = 49] = "_1";
|
|
344
|
-
CharacterCodes2[CharacterCodes2["_2"] = 50] = "_2";
|
|
345
|
-
CharacterCodes2[CharacterCodes2["_3"] = 51] = "_3";
|
|
346
|
-
CharacterCodes2[CharacterCodes2["_4"] = 52] = "_4";
|
|
347
|
-
CharacterCodes2[CharacterCodes2["_5"] = 53] = "_5";
|
|
348
|
-
CharacterCodes2[CharacterCodes2["_6"] = 54] = "_6";
|
|
349
|
-
CharacterCodes2[CharacterCodes2["_7"] = 55] = "_7";
|
|
350
|
-
CharacterCodes2[CharacterCodes2["_8"] = 56] = "_8";
|
|
351
|
-
CharacterCodes2[CharacterCodes2["_9"] = 57] = "_9";
|
|
352
|
-
CharacterCodes2[CharacterCodes2["a"] = 97] = "a";
|
|
353
|
-
CharacterCodes2[CharacterCodes2["b"] = 98] = "b";
|
|
354
|
-
CharacterCodes2[CharacterCodes2["c"] = 99] = "c";
|
|
355
|
-
CharacterCodes2[CharacterCodes2["d"] = 100] = "d";
|
|
356
|
-
CharacterCodes2[CharacterCodes2["e"] = 101] = "e";
|
|
357
|
-
CharacterCodes2[CharacterCodes2["f"] = 102] = "f";
|
|
358
|
-
CharacterCodes2[CharacterCodes2["g"] = 103] = "g";
|
|
359
|
-
CharacterCodes2[CharacterCodes2["h"] = 104] = "h";
|
|
360
|
-
CharacterCodes2[CharacterCodes2["i"] = 105] = "i";
|
|
361
|
-
CharacterCodes2[CharacterCodes2["j"] = 106] = "j";
|
|
362
|
-
CharacterCodes2[CharacterCodes2["k"] = 107] = "k";
|
|
363
|
-
CharacterCodes2[CharacterCodes2["l"] = 108] = "l";
|
|
364
|
-
CharacterCodes2[CharacterCodes2["m"] = 109] = "m";
|
|
365
|
-
CharacterCodes2[CharacterCodes2["n"] = 110] = "n";
|
|
366
|
-
CharacterCodes2[CharacterCodes2["o"] = 111] = "o";
|
|
367
|
-
CharacterCodes2[CharacterCodes2["p"] = 112] = "p";
|
|
368
|
-
CharacterCodes2[CharacterCodes2["q"] = 113] = "q";
|
|
369
|
-
CharacterCodes2[CharacterCodes2["r"] = 114] = "r";
|
|
370
|
-
CharacterCodes2[CharacterCodes2["s"] = 115] = "s";
|
|
371
|
-
CharacterCodes2[CharacterCodes2["t"] = 116] = "t";
|
|
372
|
-
CharacterCodes2[CharacterCodes2["u"] = 117] = "u";
|
|
373
|
-
CharacterCodes2[CharacterCodes2["v"] = 118] = "v";
|
|
374
|
-
CharacterCodes2[CharacterCodes2["w"] = 119] = "w";
|
|
375
|
-
CharacterCodes2[CharacterCodes2["x"] = 120] = "x";
|
|
376
|
-
CharacterCodes2[CharacterCodes2["y"] = 121] = "y";
|
|
377
|
-
CharacterCodes2[CharacterCodes2["z"] = 122] = "z";
|
|
378
|
-
CharacterCodes2[CharacterCodes2["A"] = 65] = "A";
|
|
379
|
-
CharacterCodes2[CharacterCodes2["B"] = 66] = "B";
|
|
380
|
-
CharacterCodes2[CharacterCodes2["C"] = 67] = "C";
|
|
381
|
-
CharacterCodes2[CharacterCodes2["D"] = 68] = "D";
|
|
382
|
-
CharacterCodes2[CharacterCodes2["E"] = 69] = "E";
|
|
383
|
-
CharacterCodes2[CharacterCodes2["F"] = 70] = "F";
|
|
384
|
-
CharacterCodes2[CharacterCodes2["G"] = 71] = "G";
|
|
385
|
-
CharacterCodes2[CharacterCodes2["H"] = 72] = "H";
|
|
386
|
-
CharacterCodes2[CharacterCodes2["I"] = 73] = "I";
|
|
387
|
-
CharacterCodes2[CharacterCodes2["J"] = 74] = "J";
|
|
388
|
-
CharacterCodes2[CharacterCodes2["K"] = 75] = "K";
|
|
389
|
-
CharacterCodes2[CharacterCodes2["L"] = 76] = "L";
|
|
390
|
-
CharacterCodes2[CharacterCodes2["M"] = 77] = "M";
|
|
391
|
-
CharacterCodes2[CharacterCodes2["N"] = 78] = "N";
|
|
392
|
-
CharacterCodes2[CharacterCodes2["O"] = 79] = "O";
|
|
393
|
-
CharacterCodes2[CharacterCodes2["P"] = 80] = "P";
|
|
394
|
-
CharacterCodes2[CharacterCodes2["Q"] = 81] = "Q";
|
|
395
|
-
CharacterCodes2[CharacterCodes2["R"] = 82] = "R";
|
|
396
|
-
CharacterCodes2[CharacterCodes2["S"] = 83] = "S";
|
|
397
|
-
CharacterCodes2[CharacterCodes2["T"] = 84] = "T";
|
|
398
|
-
CharacterCodes2[CharacterCodes2["U"] = 85] = "U";
|
|
399
|
-
CharacterCodes2[CharacterCodes2["V"] = 86] = "V";
|
|
400
|
-
CharacterCodes2[CharacterCodes2["W"] = 87] = "W";
|
|
401
|
-
CharacterCodes2[CharacterCodes2["X"] = 88] = "X";
|
|
402
|
-
CharacterCodes2[CharacterCodes2["Y"] = 89] = "Y";
|
|
403
|
-
CharacterCodes2[CharacterCodes2["Z"] = 90] = "Z";
|
|
404
|
-
CharacterCodes2[CharacterCodes2["asterisk"] = 42] = "asterisk";
|
|
405
|
-
CharacterCodes2[CharacterCodes2["backslash"] = 92] = "backslash";
|
|
406
|
-
CharacterCodes2[CharacterCodes2["closeBrace"] = 125] = "closeBrace";
|
|
407
|
-
CharacterCodes2[CharacterCodes2["closeBracket"] = 93] = "closeBracket";
|
|
408
|
-
CharacterCodes2[CharacterCodes2["colon"] = 58] = "colon";
|
|
409
|
-
CharacterCodes2[CharacterCodes2["comma"] = 44] = "comma";
|
|
410
|
-
CharacterCodes2[CharacterCodes2["dot"] = 46] = "dot";
|
|
411
|
-
CharacterCodes2[CharacterCodes2["doubleQuote"] = 34] = "doubleQuote";
|
|
412
|
-
CharacterCodes2[CharacterCodes2["minus"] = 45] = "minus";
|
|
413
|
-
CharacterCodes2[CharacterCodes2["openBrace"] = 123] = "openBrace";
|
|
414
|
-
CharacterCodes2[CharacterCodes2["openBracket"] = 91] = "openBracket";
|
|
415
|
-
CharacterCodes2[CharacterCodes2["plus"] = 43] = "plus";
|
|
416
|
-
CharacterCodes2[CharacterCodes2["slash"] = 47] = "slash";
|
|
417
|
-
CharacterCodes2[CharacterCodes2["formFeed"] = 12] = "formFeed";
|
|
418
|
-
CharacterCodes2[CharacterCodes2["tab"] = 9] = "tab";
|
|
419
|
-
})(CharacterCodes || (CharacterCodes = {}));
|
|
420
|
-
|
|
421
|
-
// node_modules/jsonc-parser/lib/esm/impl/string-intern.js
|
|
422
|
-
var cachedSpaces = new Array(20).fill(0).map((_, index) => {
|
|
423
|
-
return " ".repeat(index);
|
|
424
|
-
});
|
|
425
|
-
var maxCachedValues = 200;
|
|
426
|
-
var cachedBreakLinesWithSpaces = {
|
|
427
|
-
" ": {
|
|
428
|
-
"\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
429
|
-
return `
|
|
430
|
-
` + " ".repeat(index);
|
|
431
|
-
}),
|
|
432
|
-
"\r": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
433
|
-
return "\r" + " ".repeat(index);
|
|
434
|
-
}),
|
|
435
|
-
"\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
436
|
-
return `\r
|
|
437
|
-
` + " ".repeat(index);
|
|
438
|
-
})
|
|
439
|
-
},
|
|
440
|
-
"\t": {
|
|
441
|
-
"\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
442
|
-
return `
|
|
443
|
-
` + "\t".repeat(index);
|
|
444
|
-
}),
|
|
445
|
-
"\r": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
446
|
-
return "\r" + "\t".repeat(index);
|
|
447
|
-
}),
|
|
448
|
-
"\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
449
|
-
return `\r
|
|
450
|
-
` + "\t".repeat(index);
|
|
451
|
-
})
|
|
452
|
-
}
|
|
453
|
-
};
|
|
454
|
-
|
|
455
|
-
// node_modules/jsonc-parser/lib/esm/impl/parser.js
|
|
456
|
-
var ParseOptions;
|
|
457
|
-
(function(ParseOptions2) {
|
|
458
|
-
ParseOptions2.DEFAULT = {
|
|
459
|
-
allowTrailingComma: false
|
|
460
|
-
};
|
|
461
|
-
})(ParseOptions || (ParseOptions = {}));
|
|
462
|
-
function parse(text, errors = [], options = ParseOptions.DEFAULT) {
|
|
463
|
-
let currentProperty = null;
|
|
464
|
-
let currentParent = [];
|
|
465
|
-
const previousParents = [];
|
|
466
|
-
function onValue(value) {
|
|
467
|
-
if (Array.isArray(currentParent)) {
|
|
468
|
-
currentParent.push(value);
|
|
469
|
-
} else if (currentProperty !== null) {
|
|
470
|
-
currentParent[currentProperty] = value;
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
const visitor = {
|
|
474
|
-
onObjectBegin: () => {
|
|
475
|
-
const object = {};
|
|
476
|
-
onValue(object);
|
|
477
|
-
previousParents.push(currentParent);
|
|
478
|
-
currentParent = object;
|
|
479
|
-
currentProperty = null;
|
|
480
|
-
},
|
|
481
|
-
onObjectProperty: (name) => {
|
|
482
|
-
currentProperty = name;
|
|
483
|
-
},
|
|
484
|
-
onObjectEnd: () => {
|
|
485
|
-
currentParent = previousParents.pop();
|
|
486
|
-
},
|
|
487
|
-
onArrayBegin: () => {
|
|
488
|
-
const array = [];
|
|
489
|
-
onValue(array);
|
|
490
|
-
previousParents.push(currentParent);
|
|
491
|
-
currentParent = array;
|
|
492
|
-
currentProperty = null;
|
|
493
|
-
},
|
|
494
|
-
onArrayEnd: () => {
|
|
495
|
-
currentParent = previousParents.pop();
|
|
496
|
-
},
|
|
497
|
-
onLiteralValue: onValue,
|
|
498
|
-
onError: (error, offset, length) => {
|
|
499
|
-
errors.push({ error, offset, length });
|
|
500
|
-
}
|
|
501
|
-
};
|
|
502
|
-
visit(text, visitor, options);
|
|
503
|
-
return currentParent[0];
|
|
504
|
-
}
|
|
505
|
-
function visit(text, visitor, options = ParseOptions.DEFAULT) {
|
|
506
|
-
const _scanner = createScanner(text, false);
|
|
507
|
-
const _jsonPath = [];
|
|
508
|
-
let suppressedCallbacks = 0;
|
|
509
|
-
function toNoArgVisit(visitFunction) {
|
|
510
|
-
return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
|
|
511
|
-
}
|
|
512
|
-
function toOneArgVisit(visitFunction) {
|
|
513
|
-
return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
|
|
514
|
-
}
|
|
515
|
-
function toOneArgVisitWithPath(visitFunction) {
|
|
516
|
-
return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;
|
|
517
|
-
}
|
|
518
|
-
function toBeginVisit(visitFunction) {
|
|
519
|
-
return visitFunction ? () => {
|
|
520
|
-
if (suppressedCallbacks > 0) {
|
|
521
|
-
suppressedCallbacks++;
|
|
522
|
-
} else {
|
|
523
|
-
let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());
|
|
524
|
-
if (cbReturn === false) {
|
|
525
|
-
suppressedCallbacks = 1;
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
} : () => true;
|
|
529
|
-
}
|
|
530
|
-
function toEndVisit(visitFunction) {
|
|
531
|
-
return visitFunction ? () => {
|
|
532
|
-
if (suppressedCallbacks > 0) {
|
|
533
|
-
suppressedCallbacks--;
|
|
534
|
-
}
|
|
535
|
-
if (suppressedCallbacks === 0) {
|
|
536
|
-
visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());
|
|
537
|
-
}
|
|
538
|
-
} : () => true;
|
|
539
|
-
}
|
|
540
|
-
const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);
|
|
541
|
-
const disallowComments = options && options.disallowComments;
|
|
542
|
-
const allowTrailingComma = options && options.allowTrailingComma;
|
|
543
|
-
function scanNext() {
|
|
544
|
-
while (true) {
|
|
545
|
-
const token = _scanner.scan();
|
|
546
|
-
switch (_scanner.getTokenError()) {
|
|
547
|
-
case 4:
|
|
548
|
-
handleError(14);
|
|
549
|
-
break;
|
|
550
|
-
case 5:
|
|
551
|
-
handleError(15);
|
|
552
|
-
break;
|
|
553
|
-
case 3:
|
|
554
|
-
handleError(13);
|
|
555
|
-
break;
|
|
556
|
-
case 1:
|
|
557
|
-
if (!disallowComments) {
|
|
558
|
-
handleError(11);
|
|
559
|
-
}
|
|
560
|
-
break;
|
|
561
|
-
case 2:
|
|
562
|
-
handleError(12);
|
|
563
|
-
break;
|
|
564
|
-
case 6:
|
|
565
|
-
handleError(16);
|
|
566
|
-
break;
|
|
567
|
-
}
|
|
568
|
-
switch (token) {
|
|
569
|
-
case 12:
|
|
570
|
-
case 13:
|
|
571
|
-
if (disallowComments) {
|
|
572
|
-
handleError(10);
|
|
573
|
-
} else {
|
|
574
|
-
onComment();
|
|
575
|
-
}
|
|
576
|
-
break;
|
|
577
|
-
case 16:
|
|
578
|
-
handleError(1);
|
|
579
|
-
break;
|
|
580
|
-
case 15:
|
|
581
|
-
case 14:
|
|
582
|
-
break;
|
|
583
|
-
default:
|
|
584
|
-
return token;
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
function handleError(error, skipUntilAfter = [], skipUntil = []) {
|
|
589
|
-
onError(error);
|
|
590
|
-
if (skipUntilAfter.length + skipUntil.length > 0) {
|
|
591
|
-
let token = _scanner.getToken();
|
|
592
|
-
while (token !== 17) {
|
|
593
|
-
if (skipUntilAfter.indexOf(token) !== -1) {
|
|
594
|
-
scanNext();
|
|
595
|
-
break;
|
|
596
|
-
} else if (skipUntil.indexOf(token) !== -1) {
|
|
597
|
-
break;
|
|
598
|
-
}
|
|
599
|
-
token = scanNext();
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
function parseString(isValue) {
|
|
604
|
-
const value = _scanner.getTokenValue();
|
|
605
|
-
if (isValue) {
|
|
606
|
-
onLiteralValue(value);
|
|
607
|
-
} else {
|
|
608
|
-
onObjectProperty(value);
|
|
609
|
-
_jsonPath.push(value);
|
|
610
|
-
}
|
|
611
|
-
scanNext();
|
|
612
|
-
return true;
|
|
613
|
-
}
|
|
614
|
-
function parseLiteral() {
|
|
615
|
-
switch (_scanner.getToken()) {
|
|
616
|
-
case 11:
|
|
617
|
-
const tokenValue = _scanner.getTokenValue();
|
|
618
|
-
let value = Number(tokenValue);
|
|
619
|
-
if (isNaN(value)) {
|
|
620
|
-
handleError(2);
|
|
621
|
-
value = 0;
|
|
622
|
-
}
|
|
623
|
-
onLiteralValue(value);
|
|
624
|
-
break;
|
|
625
|
-
case 7:
|
|
626
|
-
onLiteralValue(null);
|
|
627
|
-
break;
|
|
628
|
-
case 8:
|
|
629
|
-
onLiteralValue(true);
|
|
630
|
-
break;
|
|
631
|
-
case 9:
|
|
632
|
-
onLiteralValue(false);
|
|
633
|
-
break;
|
|
634
|
-
default:
|
|
635
|
-
return false;
|
|
636
|
-
}
|
|
637
|
-
scanNext();
|
|
638
|
-
return true;
|
|
639
|
-
}
|
|
640
|
-
function parseProperty() {
|
|
641
|
-
if (_scanner.getToken() !== 10) {
|
|
642
|
-
handleError(3, [], [2, 5]);
|
|
643
|
-
return false;
|
|
644
|
-
}
|
|
645
|
-
parseString(false);
|
|
646
|
-
if (_scanner.getToken() === 6) {
|
|
647
|
-
onSeparator(":");
|
|
648
|
-
scanNext();
|
|
649
|
-
if (!parseValue()) {
|
|
650
|
-
handleError(4, [], [2, 5]);
|
|
651
|
-
}
|
|
652
|
-
} else {
|
|
653
|
-
handleError(5, [], [2, 5]);
|
|
654
|
-
}
|
|
655
|
-
_jsonPath.pop();
|
|
656
|
-
return true;
|
|
657
|
-
}
|
|
658
|
-
function parseObject() {
|
|
659
|
-
onObjectBegin();
|
|
660
|
-
scanNext();
|
|
661
|
-
let needsComma = false;
|
|
662
|
-
while (_scanner.getToken() !== 2 && _scanner.getToken() !== 17) {
|
|
663
|
-
if (_scanner.getToken() === 5) {
|
|
664
|
-
if (!needsComma) {
|
|
665
|
-
handleError(4, [], []);
|
|
666
|
-
}
|
|
667
|
-
onSeparator(",");
|
|
668
|
-
scanNext();
|
|
669
|
-
if (_scanner.getToken() === 2 && allowTrailingComma) {
|
|
670
|
-
break;
|
|
671
|
-
}
|
|
672
|
-
} else if (needsComma) {
|
|
673
|
-
handleError(6, [], []);
|
|
674
|
-
}
|
|
675
|
-
if (!parseProperty()) {
|
|
676
|
-
handleError(4, [], [2, 5]);
|
|
677
|
-
}
|
|
678
|
-
needsComma = true;
|
|
679
|
-
}
|
|
680
|
-
onObjectEnd();
|
|
681
|
-
if (_scanner.getToken() !== 2) {
|
|
682
|
-
handleError(7, [2], []);
|
|
683
|
-
} else {
|
|
684
|
-
scanNext();
|
|
685
|
-
}
|
|
686
|
-
return true;
|
|
687
|
-
}
|
|
688
|
-
function parseArray() {
|
|
689
|
-
onArrayBegin();
|
|
690
|
-
scanNext();
|
|
691
|
-
let isFirstElement = true;
|
|
692
|
-
let needsComma = false;
|
|
693
|
-
while (_scanner.getToken() !== 4 && _scanner.getToken() !== 17) {
|
|
694
|
-
if (_scanner.getToken() === 5) {
|
|
695
|
-
if (!needsComma) {
|
|
696
|
-
handleError(4, [], []);
|
|
697
|
-
}
|
|
698
|
-
onSeparator(",");
|
|
699
|
-
scanNext();
|
|
700
|
-
if (_scanner.getToken() === 4 && allowTrailingComma) {
|
|
701
|
-
break;
|
|
702
|
-
}
|
|
703
|
-
} else if (needsComma) {
|
|
704
|
-
handleError(6, [], []);
|
|
705
|
-
}
|
|
706
|
-
if (isFirstElement) {
|
|
707
|
-
_jsonPath.push(0);
|
|
708
|
-
isFirstElement = false;
|
|
709
|
-
} else {
|
|
710
|
-
_jsonPath[_jsonPath.length - 1]++;
|
|
711
|
-
}
|
|
712
|
-
if (!parseValue()) {
|
|
713
|
-
handleError(4, [], [4, 5]);
|
|
714
|
-
}
|
|
715
|
-
needsComma = true;
|
|
716
|
-
}
|
|
717
|
-
onArrayEnd();
|
|
718
|
-
if (!isFirstElement) {
|
|
719
|
-
_jsonPath.pop();
|
|
720
|
-
}
|
|
721
|
-
if (_scanner.getToken() !== 4) {
|
|
722
|
-
handleError(8, [4], []);
|
|
723
|
-
} else {
|
|
724
|
-
scanNext();
|
|
725
|
-
}
|
|
726
|
-
return true;
|
|
727
|
-
}
|
|
728
|
-
function parseValue() {
|
|
729
|
-
switch (_scanner.getToken()) {
|
|
730
|
-
case 3:
|
|
731
|
-
return parseArray();
|
|
732
|
-
case 1:
|
|
733
|
-
return parseObject();
|
|
734
|
-
case 10:
|
|
735
|
-
return parseString(true);
|
|
736
|
-
default:
|
|
737
|
-
return parseLiteral();
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
scanNext();
|
|
741
|
-
if (_scanner.getToken() === 17) {
|
|
742
|
-
if (options.allowEmptyContent) {
|
|
743
|
-
return true;
|
|
744
|
-
}
|
|
745
|
-
handleError(4, [], []);
|
|
746
|
-
return false;
|
|
747
|
-
}
|
|
748
|
-
if (!parseValue()) {
|
|
749
|
-
handleError(4, [], []);
|
|
750
|
-
return false;
|
|
751
|
-
}
|
|
752
|
-
if (_scanner.getToken() !== 17) {
|
|
753
|
-
handleError(9, [], []);
|
|
754
|
-
}
|
|
755
|
-
return true;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
// node_modules/jsonc-parser/lib/esm/main.js
|
|
759
|
-
var ScanError;
|
|
760
|
-
(function(ScanError2) {
|
|
761
|
-
ScanError2[ScanError2["None"] = 0] = "None";
|
|
762
|
-
ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
|
|
763
|
-
ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
|
|
764
|
-
ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
|
|
765
|
-
ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
|
|
766
|
-
ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
|
|
767
|
-
ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
|
|
768
|
-
})(ScanError || (ScanError = {}));
|
|
769
|
-
var SyntaxKind;
|
|
770
|
-
(function(SyntaxKind2) {
|
|
771
|
-
SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
|
|
772
|
-
SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
|
|
773
|
-
SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
|
|
774
|
-
SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
|
|
775
|
-
SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
|
|
776
|
-
SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
|
|
777
|
-
SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
|
|
778
|
-
SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
|
|
779
|
-
SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
|
|
780
|
-
SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
|
|
781
|
-
SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
|
|
782
|
-
SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
|
|
783
|
-
SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
|
|
784
|
-
SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
|
|
785
|
-
SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
|
|
786
|
-
SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
|
|
787
|
-
SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
|
|
788
|
-
})(SyntaxKind || (SyntaxKind = {}));
|
|
789
|
-
var parse2 = parse;
|
|
790
|
-
var ParseErrorCode;
|
|
791
|
-
(function(ParseErrorCode2) {
|
|
792
|
-
ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
|
|
793
|
-
ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
|
|
794
|
-
ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
|
|
795
|
-
ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
|
|
796
|
-
ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
|
|
797
|
-
ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
|
|
798
|
-
ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
|
|
799
|
-
ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
|
|
800
|
-
ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
|
|
801
|
-
ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
|
|
802
|
-
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
|
|
803
|
-
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
|
|
804
|
-
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
|
|
805
|
-
ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
|
|
806
|
-
ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
|
|
807
|
-
ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
|
|
808
|
-
})(ParseErrorCode || (ParseErrorCode = {}));
|
|
809
|
-
|
|
810
|
-
// src/lib/config.ts
|
|
811
|
-
import { readFileSync } from "fs";
|
|
812
|
-
import { join as join2 } from "path";
|
|
813
|
-
|
|
814
|
-
// src/constants.ts
|
|
815
|
-
var DEFAULTS = {
|
|
816
|
-
configPath: ".context/config.jsonc",
|
|
817
|
-
promptDir: ".context/prompts",
|
|
818
|
-
turnStartFile: "turn-start.md",
|
|
819
|
-
turnEndFile: "turn-end.md",
|
|
820
|
-
knowledgeSources: ["AGENTS.md"],
|
|
821
|
-
templateDir: ".context/templates",
|
|
822
|
-
indexFilename: "INDEX.md",
|
|
823
|
-
maxDomainDepth: 2,
|
|
824
|
-
knowledgeDir: "docs",
|
|
825
|
-
guidesDir: ".context/guides",
|
|
826
|
-
workCompleteFile: ".context/.work-complete"
|
|
827
|
-
};
|
|
828
|
-
var LIMITS = {
|
|
829
|
-
maxPromptFileSize: 64 * 1024,
|
|
830
|
-
maxIndexEntries: 100,
|
|
831
|
-
maxTotalInjectionSize: 128 * 1024,
|
|
832
|
-
maxScanDepth: 3,
|
|
833
|
-
maxSummaryLength: 100,
|
|
834
|
-
maxIndexFileSize: 32 * 1024
|
|
835
|
-
};
|
|
3
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, statSync, unlinkSync } from "fs";
|
|
4
|
+
import { join as join3, dirname } from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
836
6
|
|
|
837
7
|
// src/lib/context-dir.ts
|
|
838
8
|
import { existsSync } from "fs";
|
|
@@ -849,287 +19,13 @@ function resolveContextDir(projectDir) {
|
|
|
849
19
|
return nextContextDir;
|
|
850
20
|
}
|
|
851
21
|
|
|
852
|
-
// src/lib/config.ts
|
|
853
|
-
function getDefaultConfig() {
|
|
854
|
-
return {
|
|
855
|
-
prompts: {
|
|
856
|
-
turnStart: join2(DEFAULTS.promptDir, DEFAULTS.turnStartFile),
|
|
857
|
-
turnEnd: join2(DEFAULTS.promptDir, DEFAULTS.turnEndFile)
|
|
858
|
-
},
|
|
859
|
-
knowledge: {
|
|
860
|
-
dir: "docs",
|
|
861
|
-
sources: [...DEFAULTS.knowledgeSources],
|
|
862
|
-
mode: "auto",
|
|
863
|
-
indexFilename: DEFAULTS.indexFilename,
|
|
864
|
-
maxDomainDepth: DEFAULTS.maxDomainDepth
|
|
865
|
-
},
|
|
866
|
-
omx: {
|
|
867
|
-
turnEnd: {
|
|
868
|
-
strategy: "turn-complete-sendkeys"
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
};
|
|
872
|
-
}
|
|
873
|
-
function mergeWithDefaults(partial) {
|
|
874
|
-
const defaults = getDefaultConfig();
|
|
875
|
-
return {
|
|
876
|
-
prompts: {
|
|
877
|
-
turnStart: partial.prompts?.turnStart ?? defaults.prompts.turnStart,
|
|
878
|
-
turnEnd: partial.prompts?.turnEnd ?? defaults.prompts.turnEnd
|
|
879
|
-
},
|
|
880
|
-
knowledge: {
|
|
881
|
-
dir: partial.knowledge?.dir ?? defaults.knowledge.dir,
|
|
882
|
-
sources: partial.knowledge?.sources ?? defaults.knowledge.sources,
|
|
883
|
-
mode: partial.knowledge?.mode ?? defaults.knowledge.mode,
|
|
884
|
-
indexFilename: partial.knowledge?.indexFilename ?? defaults.knowledge.indexFilename,
|
|
885
|
-
maxDomainDepth: partial.knowledge?.maxDomainDepth ?? defaults.knowledge.maxDomainDepth
|
|
886
|
-
},
|
|
887
|
-
omx: {
|
|
888
|
-
turnEnd: {
|
|
889
|
-
strategy: partial.omx?.turnEnd?.strategy ?? defaults.omx?.turnEnd?.strategy
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
};
|
|
893
|
-
}
|
|
894
|
-
function loadConfig(projectDir) {
|
|
895
|
-
const configPath = join2(projectDir, resolveContextDir(projectDir), "config.jsonc");
|
|
896
|
-
try {
|
|
897
|
-
const raw = readFileSync(configPath, "utf-8");
|
|
898
|
-
const parsed = parse2(raw);
|
|
899
|
-
if (!parsed || typeof parsed !== "object")
|
|
900
|
-
return getDefaultConfig();
|
|
901
|
-
return mergeWithDefaults(parsed);
|
|
902
|
-
} catch {
|
|
903
|
-
return getDefaultConfig();
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
// src/lib/knowledge-index.ts
|
|
908
|
-
import { readdirSync, readFileSync as readFileSync2, statSync, existsSync as existsSync2 } from "fs";
|
|
909
|
-
import { join as join3, relative, extname } from "path";
|
|
910
|
-
function extractSummary(filePath) {
|
|
911
|
-
try {
|
|
912
|
-
const content = readFileSync2(filePath, "utf-8");
|
|
913
|
-
const firstNonEmpty = content.split(`
|
|
914
|
-
`).find((line) => line.trim().length > 0);
|
|
915
|
-
if (!firstNonEmpty)
|
|
916
|
-
return "";
|
|
917
|
-
return firstNonEmpty.trim().slice(0, LIMITS.maxSummaryLength);
|
|
918
|
-
} catch {
|
|
919
|
-
return "";
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
function scanDir(dir, projectDir, depth, entries) {
|
|
923
|
-
if (depth > LIMITS.maxScanDepth)
|
|
924
|
-
return;
|
|
925
|
-
if (entries.length >= LIMITS.maxIndexEntries)
|
|
926
|
-
return;
|
|
927
|
-
try {
|
|
928
|
-
const items = readdirSync(dir);
|
|
929
|
-
for (const item of items) {
|
|
930
|
-
if (entries.length >= LIMITS.maxIndexEntries)
|
|
931
|
-
break;
|
|
932
|
-
const fullPath = join3(dir, item);
|
|
933
|
-
try {
|
|
934
|
-
const stat = statSync(fullPath);
|
|
935
|
-
if (stat.isDirectory()) {
|
|
936
|
-
scanDir(fullPath, projectDir, depth + 1, entries);
|
|
937
|
-
} else if (stat.isFile() && extname(item) === ".md") {
|
|
938
|
-
entries.push({
|
|
939
|
-
filename: relative(projectDir, fullPath),
|
|
940
|
-
summary: extractSummary(fullPath)
|
|
941
|
-
});
|
|
942
|
-
}
|
|
943
|
-
} catch {}
|
|
944
|
-
}
|
|
945
|
-
} catch {}
|
|
946
|
-
}
|
|
947
|
-
function buildKnowledgeIndex(projectDir, sources) {
|
|
948
|
-
const entries = [];
|
|
949
|
-
for (const source of sources) {
|
|
950
|
-
if (entries.length >= LIMITS.maxIndexEntries)
|
|
951
|
-
break;
|
|
952
|
-
const fullPath = join3(projectDir, source);
|
|
953
|
-
if (!existsSync2(fullPath))
|
|
954
|
-
continue;
|
|
955
|
-
try {
|
|
956
|
-
const stat = statSync(fullPath);
|
|
957
|
-
if (stat.isFile() && extname(source) === ".md") {
|
|
958
|
-
entries.push({
|
|
959
|
-
filename: source,
|
|
960
|
-
summary: extractSummary(fullPath)
|
|
961
|
-
});
|
|
962
|
-
} else if (stat.isDirectory()) {
|
|
963
|
-
scanDir(fullPath, projectDir, 1, entries);
|
|
964
|
-
}
|
|
965
|
-
} catch {}
|
|
966
|
-
}
|
|
967
|
-
return entries;
|
|
968
|
-
}
|
|
969
|
-
function formatKnowledgeIndex(entries) {
|
|
970
|
-
if (entries.length === 0)
|
|
971
|
-
return "";
|
|
972
|
-
const lines = ["## Available Knowledge", ""];
|
|
973
|
-
for (const entry of entries) {
|
|
974
|
-
lines.push(`- ${entry.filename}${entry.summary ? ` \u2014 ${entry.summary}` : ""}`);
|
|
975
|
-
}
|
|
976
|
-
return lines.join(`
|
|
977
|
-
`);
|
|
978
|
-
}
|
|
979
|
-
function countMdFiles(dir, indexFilename) {
|
|
980
|
-
try {
|
|
981
|
-
const items = readdirSync(dir);
|
|
982
|
-
return items.filter((item) => extname(item) === ".md" && item !== indexFilename && statSync(join3(dir, item)).isFile()).length;
|
|
983
|
-
} catch {
|
|
984
|
-
return 0;
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
function scanDomainsRecursive(baseDir, projectDir, indexFilename, currentDepth, maxDepth, results) {
|
|
988
|
-
if (currentDepth > maxDepth)
|
|
989
|
-
return;
|
|
990
|
-
try {
|
|
991
|
-
const items = readdirSync(baseDir);
|
|
992
|
-
for (const item of items) {
|
|
993
|
-
const fullPath = join3(baseDir, item);
|
|
994
|
-
try {
|
|
995
|
-
if (!statSync(fullPath).isDirectory())
|
|
996
|
-
continue;
|
|
997
|
-
const indexPath = join3(fullPath, indexFilename);
|
|
998
|
-
if (existsSync2(indexPath) && statSync(indexPath).isFile()) {
|
|
999
|
-
const rawContent = readFileSync2(indexPath, "utf-8");
|
|
1000
|
-
const indexContent = rawContent.slice(0, LIMITS.maxIndexFileSize);
|
|
1001
|
-
results.push({
|
|
1002
|
-
domain: item,
|
|
1003
|
-
path: relative(projectDir, fullPath),
|
|
1004
|
-
indexContent,
|
|
1005
|
-
noteCount: countMdFiles(fullPath, indexFilename)
|
|
1006
|
-
});
|
|
1007
|
-
}
|
|
1008
|
-
scanDomainsRecursive(fullPath, projectDir, indexFilename, currentDepth + 1, maxDepth, results);
|
|
1009
|
-
} catch {}
|
|
1010
|
-
}
|
|
1011
|
-
} catch {}
|
|
1012
|
-
}
|
|
1013
|
-
function scanDomains(projectDir, knowledgeDir, indexFilename, maxDepth) {
|
|
1014
|
-
const baseDir = join3(projectDir, knowledgeDir);
|
|
1015
|
-
if (!existsSync2(baseDir))
|
|
1016
|
-
return [];
|
|
1017
|
-
const results = [];
|
|
1018
|
-
scanDomainsRecursive(baseDir, projectDir, indexFilename, 1, maxDepth, results);
|
|
1019
|
-
return results;
|
|
1020
|
-
}
|
|
1021
|
-
function detectKnowledgeMode(projectDir, knowledgeDir, indexFilename, configMode) {
|
|
1022
|
-
if (configMode !== "auto")
|
|
1023
|
-
return configMode;
|
|
1024
|
-
const domains = scanDomains(projectDir, knowledgeDir, indexFilename, 1);
|
|
1025
|
-
return domains.length > 0 ? "domain" : "flat";
|
|
1026
|
-
}
|
|
1027
|
-
function formatDomainIndex(index) {
|
|
1028
|
-
const hasDomains = index.domains.length > 0;
|
|
1029
|
-
const hasFiles = index.individualFiles.length > 0;
|
|
1030
|
-
if (!hasDomains && !hasFiles)
|
|
1031
|
-
return "";
|
|
1032
|
-
const lines = ["## Available Knowledge", ""];
|
|
1033
|
-
if (hasDomains) {
|
|
1034
|
-
lines.push("### Domains", "");
|
|
1035
|
-
for (const domain of index.domains) {
|
|
1036
|
-
lines.push(`#### ${domain.path}/ (${domain.noteCount} notes)`, "");
|
|
1037
|
-
lines.push(domain.indexContent, "");
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
if (hasFiles) {
|
|
1041
|
-
if (hasDomains) {
|
|
1042
|
-
lines.push("### Individual Files", "");
|
|
1043
|
-
}
|
|
1044
|
-
for (const file of index.individualFiles) {
|
|
1045
|
-
lines.push(`- ${file.filename}${file.summary ? ` \u2014 ${file.summary}` : ""}`);
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
return lines.join(`
|
|
1049
|
-
`);
|
|
1050
|
-
}
|
|
1051
|
-
function collectRootFiles(projectDir, knowledgeDir, indexFilename) {
|
|
1052
|
-
const baseDir = join3(projectDir, knowledgeDir);
|
|
1053
|
-
if (!existsSync2(baseDir))
|
|
1054
|
-
return [];
|
|
1055
|
-
const entries = [];
|
|
1056
|
-
try {
|
|
1057
|
-
const items = readdirSync(baseDir);
|
|
1058
|
-
for (const item of items) {
|
|
1059
|
-
const fullPath = join3(baseDir, item);
|
|
1060
|
-
try {
|
|
1061
|
-
const stat = statSync(fullPath);
|
|
1062
|
-
if (stat.isFile() && extname(item) === ".md" && item !== indexFilename) {
|
|
1063
|
-
entries.push({
|
|
1064
|
-
filename: relative(projectDir, fullPath),
|
|
1065
|
-
summary: extractSummary(fullPath)
|
|
1066
|
-
});
|
|
1067
|
-
}
|
|
1068
|
-
} catch {}
|
|
1069
|
-
}
|
|
1070
|
-
} catch {}
|
|
1071
|
-
return entries;
|
|
1072
|
-
}
|
|
1073
|
-
function buildKnowledgeIndexV2(projectDir, knowledgeConfig) {
|
|
1074
|
-
const dir = knowledgeConfig.dir ?? "docs";
|
|
1075
|
-
const indexFilename = knowledgeConfig.indexFilename ?? "INDEX.md";
|
|
1076
|
-
const maxDepth = knowledgeConfig.maxDomainDepth ?? 2;
|
|
1077
|
-
const configMode = knowledgeConfig.mode ?? "auto";
|
|
1078
|
-
const mode = detectKnowledgeMode(projectDir, dir, indexFilename, configMode);
|
|
1079
|
-
if (mode === "flat") {
|
|
1080
|
-
const allSources = [dir, ...knowledgeConfig.sources].filter(Boolean);
|
|
1081
|
-
const entries = buildKnowledgeIndex(projectDir, allSources);
|
|
1082
|
-
return { mode: "flat", domains: [], individualFiles: entries };
|
|
1083
|
-
}
|
|
1084
|
-
const domains = scanDomains(projectDir, dir, indexFilename, maxDepth);
|
|
1085
|
-
const rootFiles = collectRootFiles(projectDir, dir, indexFilename);
|
|
1086
|
-
const sourcesEntries = [];
|
|
1087
|
-
for (const source of knowledgeConfig.sources) {
|
|
1088
|
-
const fullPath = join3(projectDir, source);
|
|
1089
|
-
if (!existsSync2(fullPath))
|
|
1090
|
-
continue;
|
|
1091
|
-
try {
|
|
1092
|
-
const stat = statSync(fullPath);
|
|
1093
|
-
if (stat.isFile() && extname(source) === ".md") {
|
|
1094
|
-
sourcesEntries.push({
|
|
1095
|
-
filename: source,
|
|
1096
|
-
summary: extractSummary(fullPath)
|
|
1097
|
-
});
|
|
1098
|
-
}
|
|
1099
|
-
} catch {}
|
|
1100
|
-
}
|
|
1101
|
-
const individualFiles = [...rootFiles, ...sourcesEntries];
|
|
1102
|
-
return { mode: "domain", domains, individualFiles };
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
// src/lib/prompt-reader.ts
|
|
1106
|
-
import { readFileSync as readFileSync3 } from "fs";
|
|
1107
|
-
function readPromptFile(filePath) {
|
|
1108
|
-
try {
|
|
1109
|
-
const content = readFileSync3(filePath, "utf-8");
|
|
1110
|
-
if (content.length > LIMITS.maxPromptFileSize) {
|
|
1111
|
-
return content.slice(0, LIMITS.maxPromptFileSize);
|
|
1112
|
-
}
|
|
1113
|
-
return content;
|
|
1114
|
-
} catch {
|
|
1115
|
-
return "";
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
function resolvePromptVariables(content, vars) {
|
|
1119
|
-
const normalized = (vars.knowledgeDir || "docs").replace(/\\/g, "/").replace(/\/+$/, "");
|
|
1120
|
-
let resolved = content.replaceAll("{{knowledgeDir}}", normalized);
|
|
1121
|
-
resolved = resolved.replaceAll("{{sessionId}}", vars.sessionId ?? "");
|
|
1122
|
-
resolved = resolved.replaceAll("{{turnId}}", vars.turnId ?? "");
|
|
1123
|
-
return resolved;
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
22
|
// src/lib/scaffold.ts
|
|
1127
|
-
import { existsSync as
|
|
1128
|
-
import { join as
|
|
23
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
24
|
+
import { join as join2 } from "path";
|
|
1129
25
|
// package.json
|
|
1130
26
|
var package_default = {
|
|
1131
27
|
name: "@ksm0709/context",
|
|
1132
|
-
version: "0.0.
|
|
28
|
+
version: "0.0.23",
|
|
1133
29
|
author: {
|
|
1134
30
|
name: "TaehoKang",
|
|
1135
31
|
email: "ksm07091@gmail.com"
|
|
@@ -1159,10 +55,10 @@ var package_default = {
|
|
|
1159
55
|
access: "public"
|
|
1160
56
|
},
|
|
1161
57
|
scripts: {
|
|
1162
|
-
build: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs",
|
|
58
|
+
build: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/mcp.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs",
|
|
1163
59
|
test: "vitest run",
|
|
1164
60
|
lint: "eslint src --ext .ts",
|
|
1165
|
-
prepublishOnly: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs"
|
|
61
|
+
prepublishOnly: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/mcp.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs"
|
|
1166
62
|
},
|
|
1167
63
|
files: [
|
|
1168
64
|
"dist"
|
|
@@ -1171,7 +67,8 @@ var package_default = {
|
|
|
1171
67
|
"@opencode-ai/plugin": ">=1.0.0"
|
|
1172
68
|
},
|
|
1173
69
|
dependencies: {
|
|
1174
|
-
"@ksm0709/context": "^0.0.
|
|
70
|
+
"@ksm0709/context": "^0.0.22",
|
|
71
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
1175
72
|
"jsonc-parser": "^3.0.0"
|
|
1176
73
|
},
|
|
1177
74
|
devDependencies: {
|
|
@@ -1196,12 +93,8 @@ var PLUGIN_VERSION = package_default.version;
|
|
|
1196
93
|
var DEFAULT_CONFIG = `{
|
|
1197
94
|
// Context Plugin Configuration
|
|
1198
95
|
// See: https://github.com/ksm0709/context
|
|
1199
|
-
"prompts": {
|
|
1200
|
-
"turnStart": "prompts/turn-start.md",
|
|
1201
|
-
"turnEnd": "prompts/turn-end.md"
|
|
1202
|
-
},
|
|
1203
96
|
"knowledge": {
|
|
1204
|
-
"dir": "
|
|
97
|
+
"dir": ".context/memory",
|
|
1205
98
|
"sources": ["AGENTS.md"]
|
|
1206
99
|
},
|
|
1207
100
|
"omx": {
|
|
@@ -1211,52 +104,6 @@ var DEFAULT_CONFIG = `{
|
|
|
1211
104
|
}
|
|
1212
105
|
}
|
|
1213
106
|
}`;
|
|
1214
|
-
var DEFAULT_TURN_START = `## Knowledge Context
|
|
1215
|
-
|
|
1216
|
-
\uC774 \uD504\uB85C\uC81D\uD2B8\uB294 **\uC81C\uD154\uCE74\uC2A4\uD150(Zettelkasten)** \uBC29\uC2DD\uC73C\uB85C \uC9C0\uC2DD\uC744 \uAD00\uB9AC\uD569\uB2C8\uB2E4.
|
|
1217
|
-
\uC138\uC158 \uAC04 \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uBCF4\uC874\uD558\uC5EC, \uC774\uC804 \uC138\uC158\uC758 \uACB0\uC815/\uD328\uD134/\uC2E4\uC218\uAC00 \uB2E4\uC74C \uC138\uC158\uC5D0\uC11C \uC7AC\uD65C\uC6A9\uB429\uB2C8\uB2E4.
|
|
1218
|
-
|
|
1219
|
-
### \uC81C\uD154\uCE74\uC2A4\uD150 \uD575\uC2EC \uC6D0\uCE59
|
|
1220
|
-
|
|
1221
|
-
1. **\uC6D0\uC790\uC131** -- \uD558\uB098\uC758 \uB178\uD2B8 = \uD558\uB098\uC758 \uC8FC\uC81C. \uC5EC\uB7EC \uC8FC\uC81C\uB97C \uC11E\uC9C0 \uB9C8\uC138\uC694.
|
|
1222
|
-
2. **\uC5F0\uACB0** -- \uBAA8\uB4E0 \uB178\uD2B8\uB294 [[wikilink]]\uB85C \uAD00\uB828 \uB178\uD2B8\uC5D0 \uC5F0\uACB0. \uACE0\uB9BD\uB41C \uB178\uD2B8\uB294 \uBC1C\uACAC\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
|
1223
|
-
3. **\uC790\uAE30 \uC5B8\uC5B4** -- \uBCF5\uC0AC-\uBD99\uC5EC\uB123\uAE30\uAC00 \uC544\uB2CC, \uD575\uC2EC\uC744 \uC774\uD574\uD558\uACE0 \uAC04\uACB0\uD558\uAC8C \uC11C\uC220\uD558\uC138\uC694.
|
|
1224
|
-
|
|
1225
|
-
### \uC791\uC5C5 \uC804 \uD544\uC218
|
|
1226
|
-
|
|
1227
|
-
- **\uB370\uC77C\uB9AC \uB178\uD2B8 \uD655\uC778**: \uAC00\uC7A5 \uCD5C\uADFC\uC758 \uB370\uC77C\uB9AC \uB178\uD2B8(\`{{knowledgeDir}}/daily/YYYY-MM-DD.md\`)\uB97C \uC77D\uACE0 \uC774\uC804 \uC138\uC158\uC758 \uCEE8\uD14D\uC2A4\uD2B8\uC640 \uBBF8\uD574\uACB0 \uC774\uC288\uB97C \uD30C\uC545\uD558\uC138\uC694
|
|
1228
|
-
- **\uC791\uC5C5 \uC758\uB3C4 \uC120\uC5B8**: \uC791\uC5C5 \uC2DC\uC791 \uC804, \uD604\uC7AC \uC138\uC158\uC758 \uBAA9\uD45C\uC640 \uC791\uC5C5 \uC758\uB3C4\uB97C \uBA85\uD655\uD788 \uD30C\uC545\uD558\uACE0 \uC120\uC5B8\uD558\uC138\uC694 (\uCD94\uD6C4 \uC791\uC5C5 \uACBD\uB85C \uAC80\uC99D \uC2DC \uAE30\uC900\uC774 \uB429\uB2C8\uB2E4)
|
|
1229
|
-
- \uBA54\uC778 \uC5D0\uC774\uC804\uD2B8\uAC00 \uC544\uB798 **Available Knowledge** \uBAA9\uB85D\uC5D0\uC11C \uD604\uC7AC \uC791\uC5C5\uACFC \uAD00\uB828\uB41C \uBB38\uC11C\uB97C **\uC9C1\uC811 \uBA3C\uC800** \uC77D\uC73C\uC138\uC694
|
|
1230
|
-
- \uB3C4\uBA54\uC778 \uD3F4\uB354 \uAD6C\uC870\uAC00 \uC788\uB2E4\uBA74 INDEX.md\uC758 \uC694\uC57D\uC744 \uCC38\uACE0\uD558\uC5EC \uD544\uC694\uD55C \uB178\uD2B8\uB9CC \uC120\uD0DD\uC801\uC73C\uB85C \uC77D\uC73C\uC138\uC694
|
|
1231
|
-
- \uBB38\uC11C \uB0B4 [[\uB9C1\uD06C]]\uB97C \uB530\uB77C\uAC00\uBA70 \uAD00\uB828 \uB178\uD2B8\uB97C \uD0D0\uC0C9\uD558\uC138\uC694 -- \uB9C1\uD06C\uB97C \uB193\uCE58\uBA74 \uC911\uC694\uD55C \uB9E5\uB77D\uC744 \uC783\uC2B5\uB2C8\uB2E4
|
|
1232
|
-
- \uC9C0\uC2DD \uD30C\uC77C\uC5D0 \uAE30\uB85D\uB41C \uC544\uD0A4\uD14D\uCC98 \uACB0\uC815, \uD328\uD134, \uC81C\uC57D\uC0AC\uD56D\uC744 \uBC18\uB4DC\uC2DC \uB530\uB974\uC138\uC694
|
|
1233
|
-
- \uC77D\uC740 \uC9C0\uC2DD\uC744 \uD604\uC7AC \uC791\uC5C5\uC758 \uC124\uACC4, \uAD6C\uD604, \uAC80\uC99D\uC5D0 \uC9C1\uC811 \uBC18\uC601\uD558\uC138\uC694
|
|
1234
|
-
|
|
1235
|
-
### \uAC1C\uBC1C \uC6D0\uCE59
|
|
1236
|
-
|
|
1237
|
-
- **TDD** (Test-Driven Development): \uD14C\uC2A4\uD2B8\uB97C \uBA3C\uC800 \uC791\uC131\uD558\uACE0(RED), \uAD6C\uD604\uD558\uC5EC \uD1B5\uACFC\uC2DC\uD0A8 \uB4A4(GREEN), \uB9AC\uD329\uD1A0\uB9C1\uD558\uC138\uC694
|
|
1238
|
-
- **DDD** (Domain-Driven Design): \uB3C4\uBA54\uC778 \uAC1C\uB150\uC744 \uCF54\uB4DC \uAD6C\uC870\uC5D0 \uBC18\uC601\uD558\uC138\uC694. \uD0C0\uC785\uACFC \uBAA8\uB4C8\uC740 \uBE44\uC988\uB2C8\uC2A4 \uB3C4\uBA54\uC778\uC744 \uAE30\uC900\uC73C\uB85C \uBD84\uB9AC\uD558\uC138\uC694
|
|
1239
|
-
- **\uD14C\uC2A4\uD2B8 \uCEE4\uBC84\uB9AC\uC9C0**: \uC0C8\uB85C \uC791\uC131\uD558\uAC70\uB098 \uBCC0\uACBD\uD55C \uCF54\uB4DC\uB294 \uD14C\uC2A4\uD2B8 \uCEE4\uBC84\uB9AC\uC9C0 80% \uC774\uC0C1\uC744 \uBAA9\uD45C\uB85C \uD558\uC138\uC694. \uAD6C\uD604 \uC804\uC5D0 \uD14C\uC2A4\uD2B8\uBD80\uD130 \uC791\uC131\uD558\uBA74 \uC790\uC5F0\uC2A4\uB7FD\uAC8C \uB2EC\uC131\uB429\uB2C8\uB2E4
|
|
1240
|
-
|
|
1241
|
-
### \uC6B0\uC120\uC21C\uC704
|
|
1242
|
-
|
|
1243
|
-
- AGENTS.md\uC758 \uC9C0\uC2DC\uC0AC\uD56D\uC774 \uD56D\uC0C1 \uCD5C\uC6B0\uC120
|
|
1244
|
-
- \uC9C0\uC2DD \uB178\uD2B8\uC758 \uACB0\uC815\uC0AC\uD56D > \uC77C\uBC18\uC801 \uAD00\uD589
|
|
1245
|
-
- \uC9C0\uC2DD \uB178\uD2B8\uC5D0 \uC5C6\uB294 \uC0C8\uB85C\uC6B4 \uACB0\uC815\uC774\uB098 \uBC18\uBCF5 \uAC00\uCE58\uAC00 \uC788\uB294 \uBC1C\uACAC\uC740 \uC791\uC5C5 \uBA54\uBAA8\uB098 \uC9C0\uC2DD \uB178\uD2B8 \uD6C4\uBCF4\uB85C \uAE30\uB85D\uD558\uC138\uC694
|
|
1246
|
-
`;
|
|
1247
|
-
var DEFAULT_TURN_END = `## TURN END \uC791\uC5C5 \uC9C0\uCE68
|
|
1248
|
-
\uC544\uB798 \uBA54\uB274 \uC911 \uD558\uB098\uB97C \uC120\uD0DD\uD574 \uC9C4\uD589 \uC0C1\uD669\uC5D0 \uB9DE\uAC8C \uC218\uD589\uD558\uC138\uC694.
|
|
1249
|
-
**\uBC18\uB4DC\uC2DC \uB9C1\uD06C\uB41C \uAC00\uC774\uB4DC\uB97C \uCC38\uACE0\uD558\uC5EC \uC815\uD655\uD788 \uC218\uD589\uD574\uC57C \uD569\uB2C8\uB2E4.**
|
|
1250
|
-
|
|
1251
|
-
1. **\uACC4\uC18D \uC791\uC5C5**: \uAE30\uC874 \uC791\uC5C5\uC774 \uC644\uB8CC\uB418\uC9C0 \uC54A\uC558\uACE0 \uC544\uC9C1 \uC544\uB798 \uC561\uC158\uC744 \uCDE8\uD560 \uB2E8\uACC4\uAC00 \uC544\uB2C8\uB77C\uBA74 \uC791\uC5C5 \uC18D\uAC1C.
|
|
1252
|
-
2. **\uB370\uC77C\uB9AC \uB178\uD2B8 \uAE30\uB85D**: [.context/guides/daily-note-guide.md] \uB370\uC77C\uB9AC \uB178\uD2B8\uC5D0 \uC911\uC694\uD55C \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uAE30\uB85D\uD558\uC5EC \uB2E4\uC74C \uC138\uC158\uC774\uB098 \uC5D0\uC774\uC804\uD2B8 \uD300\uC774 \uCC38\uACE0\uD560 \uC218 \uC788\uB3C4\uB85D \uD558\uC138\uC694. \uAE30\uC874 \uB0B4\uC6A9 \uC218\uC815\uC740 \uBD88\uAC00\uD558\uBA70, \uC0C8\uB85C\uC6B4 \uBA54\uBAA8\uB97C \uCD94\uAC00 \uD558\uB294\uAC83\uB9CC \uAC00\uB2A5\uD569\uB2C8\uB2E4. \uAC04\uB7B5\uD55C \uD55C \uB450 \uBB38\uC7A5\uC73C\uB85C \uC791\uC131\uD558\uC5EC \uD575\uC2EC \uCEE8\uD14D\uC2A4\uD2B8\uAC00 \uBA85\uD655\uD788 \uC804\uB2EC\uB418\uB3C4\uB85D \uD558\uC138\uC694.
|
|
1253
|
-
3. **\uC9C0\uC2DD \uB178\uD2B8 \uC791\uC131**: [.context/guides/note-guide.md] \uC791\uC5C5\uAE30\uC5B5(\uB370\uC77C\uB9AC\uB178\uD2B8, \uC138\uC158 \uCEE8\uD14D\uC2A4\uD2B8)\uBCF4\uB2E4 \uC624\uB798 \uAE30\uC5B5\uB418\uC5B4\uC57C \uD558\uB294 \uC911\uC694\uD55C \uACB0\uC815, \uD328\uD134, \uC2E4\uC218, \uBC1C\uACAC\uC740 \uC9C0\uC2DD \uB178\uD2B8\uB85C \uAE30\uB85D\uD558\uC5EC \uD504\uB85C\uC81D\uD2B8\uC758 \uC9D1\uB2E8 \uC9C0\uC2DD\uC73C\uB85C \uB0A8\uAE30\uC138\uC694.
|
|
1254
|
-
4. **\uB178\uD2B8/\uC2A4\uD0AC \uAC80\uC0C9 \uBC0F \uC77D\uAE30**: [.context/guides/search-guide.md] \uC5B4\uB824\uC6C0\uC5D0 \uCC98\uD588\uB2E4\uBA74 \uD604\uC7AC \uC9C4\uD589 \uC0C1\uD669\uC5D0 \uD544\uC694\uD55C \uC9C0\uC2DD\uC774\uB098 \uC2A4\uD0AC\uC774 \uC788\uB294\uC9C0 \uD655\uC778\uD558\uACE0, \uAD00\uB828 \uB178\uD2B8\uB97C \uC77D\uC5B4\uBCF4\uC138\uC694. \uC0C8\uB85C\uC6B4 \uC544\uC774\uB514\uC5B4\uB098 \uD574\uACB0\uCC45\uC774 \uB5A0\uC624\uB97C \uC218 \uC788\uC2B5\uB2C8\uB2E4.
|
|
1255
|
-
5. **\uC791\uC5C5 \uACBD\uB85C \uB9AC\uBDF0**: [.context/guides/scope-review.md] \uC0AC\uC6A9\uC790\uAC00 \uC758\uB3C4\uD55C \uC791\uC5C5 \uBC94\uC704\uB97C \uBC97\uC5B4\uB098\uC9C0 \uC54A\uC558\uB294\uC9C0, \uC791\uC5C5\uC774 \uB108\uBB34 \uD06C\uAC70\uB098 \uBCF5\uC7A1\uD574\uC9C0\uC9C0\uB294 \uC54A\uC558\uB294\uC9C0 \uAC80\uD1A0\uD558\uC138\uC694.
|
|
1256
|
-
6. **\uCCB4\uD06C\uD3EC\uC778\uD2B8 \uCEE4\uBC0B**: [.context/guides/commit-guide.md] \uC791\uC5C5\uC774 \uAE38\uC5B4\uC9C8 \uACBD\uC6B0, \uC911\uC694\uD55C \uB2E8\uACC4\uB9C8\uB2E4 \uCCB4\uD06C\uD3EC\uC778\uD2B8 \uCEE4\uBC0B\uC744 \uD558\uC5EC \uC791\uC5C5 \uB0B4\uC6A9\uC744 \uC548\uC804\uD558\uAC8C \uC800\uC7A5\uD558\uACE0, \uD544\uC694 \uC2DC \uC774\uC804 \uC0C1\uD0DC\uB85C \uB3CC\uC544\uAC08 \uC218 \uC788\uB3C4\uB85D \uD558\uC138\uC694.
|
|
1257
|
-
7. **\uD004\uB9AC\uD2F0 \uAC80\uC99D**: [.context/guides/quality-check.md] **\uC791\uC5C5 \uC644\uB8CC \uC804\uC5D0 \uBC18\uB4DC\uC2DC \uC218\uD589\uD558\uC138\uC694**. \uCF54\uB4DC \uB9B0\uD2B8, \uD3EC\uB9F7\uD130, \uD14C\uC2A4\uD2B8, \uBE4C\uB4DC, \uCF54\uB4DC\uB9AC\uBDF0\uB97C \uC2E4\uD589\uD558\uC5EC \uC791\uC5C5 \uACB0\uACFC\uBB3C\uC774 \uD504\uB85C\uC81D\uD2B8\uC758 \uD488\uC9C8 \uAE30\uC900\uC744 \uCDA9\uC871\uD558\uB294\uC9C0 \uD655\uC778\uD558\uC138\uC694.
|
|
1258
|
-
8. **\uC791\uC5C5 \uC644\uB8CC**: [.context/guides/complete-guide.md] \uBAA8\uB4E0 \uC791\uC5C5\uC774 \uC644\uB8CC\uB418\uC5C8\uB2E4\uBA74, \uC774 \uAC00\uC774\uB4DC\uB97C \uB530\uB974\uC138\uC694. \uC774 \uC791\uC5C5 \uC9C0\uCE68\uC774 \uB354\uC774\uC0C1 \uD2B8\uB9AC\uAC70\uB418\uC9C0 \uC54A\uC744 \uAC83\uC785\uB2C8\uB2E4.
|
|
1259
|
-
`;
|
|
1260
107
|
var DEFAULT_ADR_TEMPLATE = `# ADR-NNN: [\uC81C\uBAA9]
|
|
1261
108
|
|
|
1262
109
|
## \uC0C1\uD0DC
|
|
@@ -1548,25 +395,21 @@ var TEMPLATE_FILES = {
|
|
|
1548
395
|
"work-complete.txt": DEFAULT_WORK_COMPLETE_TEMPLATE
|
|
1549
396
|
};
|
|
1550
397
|
function scaffoldIfNeeded(projectDir) {
|
|
1551
|
-
const contextDir =
|
|
1552
|
-
if (
|
|
398
|
+
const contextDir = join2(projectDir, resolveContextDir(projectDir));
|
|
399
|
+
if (existsSync2(contextDir)) {
|
|
1553
400
|
return false;
|
|
1554
401
|
}
|
|
1555
402
|
try {
|
|
1556
|
-
const
|
|
1557
|
-
mkdirSync(promptsDir, { recursive: true });
|
|
1558
|
-
const templatesDir = join4(contextDir, "templates");
|
|
403
|
+
const templatesDir = join2(contextDir, "templates");
|
|
1559
404
|
mkdirSync(templatesDir, { recursive: true });
|
|
1560
|
-
const guidesDir =
|
|
405
|
+
const guidesDir = join2(contextDir, "guides");
|
|
1561
406
|
mkdirSync(guidesDir, { recursive: true });
|
|
1562
|
-
writeFileSync(
|
|
1563
|
-
writeFileSync(join4(promptsDir, DEFAULTS.turnStartFile), DEFAULT_TURN_START, "utf-8");
|
|
1564
|
-
writeFileSync(join4(promptsDir, DEFAULTS.turnEndFile), DEFAULT_TURN_END, "utf-8");
|
|
407
|
+
writeFileSync(join2(contextDir, "config.jsonc"), DEFAULT_CONFIG, "utf-8");
|
|
1565
408
|
for (const [filename, content] of Object.entries(TEMPLATE_FILES)) {
|
|
1566
|
-
writeFileSync(
|
|
409
|
+
writeFileSync(join2(templatesDir, filename), content, "utf-8");
|
|
1567
410
|
}
|
|
1568
411
|
for (const [filename, content] of Object.entries(GUIDE_FILES)) {
|
|
1569
|
-
writeFileSync(
|
|
412
|
+
writeFileSync(join2(guidesDir, filename), content, "utf-8");
|
|
1570
413
|
}
|
|
1571
414
|
writeVersion(contextDir, PLUGIN_VERSION);
|
|
1572
415
|
return true;
|
|
@@ -1576,35 +419,32 @@ function scaffoldIfNeeded(projectDir) {
|
|
|
1576
419
|
}
|
|
1577
420
|
function getStoredVersion(projectDir) {
|
|
1578
421
|
try {
|
|
1579
|
-
return
|
|
422
|
+
return readFileSync(join2(projectDir, resolveContextDir(projectDir), ".version"), "utf-8").trim();
|
|
1580
423
|
} catch {
|
|
1581
424
|
return null;
|
|
1582
425
|
}
|
|
1583
426
|
}
|
|
1584
427
|
function writeVersion(contextDir, version) {
|
|
1585
|
-
writeFileSync(
|
|
428
|
+
writeFileSync(join2(contextDir, ".version"), version, "utf-8");
|
|
1586
429
|
}
|
|
1587
430
|
function autoUpdateTemplates(projectDir) {
|
|
1588
|
-
const contextDir =
|
|
1589
|
-
if (!
|
|
431
|
+
const contextDir = join2(projectDir, resolveContextDir(projectDir));
|
|
432
|
+
if (!existsSync2(contextDir))
|
|
1590
433
|
return [];
|
|
1591
434
|
const stored = getStoredVersion(projectDir);
|
|
1592
435
|
if (stored === PLUGIN_VERSION)
|
|
1593
436
|
return [];
|
|
1594
|
-
mkdirSync(
|
|
1595
|
-
mkdirSync(
|
|
1596
|
-
mkdirSync(join4(contextDir, "guides"), { recursive: true });
|
|
437
|
+
mkdirSync(join2(contextDir, "templates"), { recursive: true });
|
|
438
|
+
mkdirSync(join2(contextDir, "guides"), { recursive: true });
|
|
1597
439
|
const filesToUpdate = {
|
|
1598
|
-
[`prompts/${DEFAULTS.turnStartFile}`]: DEFAULT_TURN_START,
|
|
1599
|
-
[`prompts/${DEFAULTS.turnEndFile}`]: DEFAULT_TURN_END,
|
|
1600
440
|
...Object.fromEntries(Object.entries(TEMPLATE_FILES).map(([f, c]) => [`templates/${f}`, c])),
|
|
1601
441
|
...Object.fromEntries(Object.entries(GUIDE_FILES).map(([f, c]) => [`guides/${f}`, c]))
|
|
1602
442
|
};
|
|
1603
443
|
const updated = [];
|
|
1604
444
|
for (const [path, content] of Object.entries(filesToUpdate)) {
|
|
1605
|
-
const filePath =
|
|
445
|
+
const filePath = join2(contextDir, path);
|
|
1606
446
|
try {
|
|
1607
|
-
const existing =
|
|
447
|
+
const existing = readFileSync(filePath, "utf-8");
|
|
1608
448
|
if (existing === content)
|
|
1609
449
|
continue;
|
|
1610
450
|
} catch {}
|
|
@@ -1615,15 +455,29 @@ function autoUpdateTemplates(projectDir) {
|
|
|
1615
455
|
return updated;
|
|
1616
456
|
}
|
|
1617
457
|
|
|
458
|
+
// src/constants.ts
|
|
459
|
+
var DEFAULTS = {
|
|
460
|
+
configPath: ".context/config.jsonc",
|
|
461
|
+
knowledgeSources: ["AGENTS.md"],
|
|
462
|
+
templateDir: ".context/templates",
|
|
463
|
+
indexFilename: "INDEX.md",
|
|
464
|
+
maxDomainDepth: 2,
|
|
465
|
+
knowledgeDir: "docs",
|
|
466
|
+
guidesDir: ".context/guides",
|
|
467
|
+
workCompleteFile: ".context/.work-complete"
|
|
468
|
+
};
|
|
469
|
+
var LIMITS = {
|
|
470
|
+
maxPromptFileSize: 64 * 1024,
|
|
471
|
+
maxIndexEntries: 100,
|
|
472
|
+
maxTotalInjectionSize: 128 * 1024,
|
|
473
|
+
maxScanDepth: 3,
|
|
474
|
+
maxSummaryLength: 100,
|
|
475
|
+
maxIndexFileSize: 32 * 1024
|
|
476
|
+
};
|
|
477
|
+
|
|
1618
478
|
// src/index.ts
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
return promptPath;
|
|
1622
|
-
if (promptPath.startsWith(".context/") || promptPath.startsWith(".opencode/")) {
|
|
1623
|
-
return join5(directory, promptPath);
|
|
1624
|
-
}
|
|
1625
|
-
return join5(directory, contextDir, promptPath);
|
|
1626
|
-
}
|
|
479
|
+
var __filename2 = fileURLToPath(import.meta.url);
|
|
480
|
+
var __dirname2 = dirname(__filename2);
|
|
1627
481
|
var plugin = async ({ directory, client }) => {
|
|
1628
482
|
const scaffolded = scaffoldIfNeeded(directory);
|
|
1629
483
|
const contextDir = resolveContextDir(directory);
|
|
@@ -1647,42 +501,33 @@ var plugin = async ({ directory, client }) => {
|
|
|
1647
501
|
});
|
|
1648
502
|
}
|
|
1649
503
|
}
|
|
1650
|
-
const config = loadConfig(directory);
|
|
1651
504
|
return {
|
|
505
|
+
config: async (config) => {
|
|
506
|
+
config.mcp = config.mcp || {};
|
|
507
|
+
config.mcp["context-mcp"] = {
|
|
508
|
+
type: "local",
|
|
509
|
+
command: ["bun", join3(__dirname2, "mcp.js")]
|
|
510
|
+
};
|
|
511
|
+
},
|
|
1652
512
|
"experimental.chat.messages.transform": async (_input, output) => {
|
|
513
|
+
if (process.env.OMX_HOOK_PLUGINS)
|
|
514
|
+
return;
|
|
1653
515
|
if (output.messages.length === 0)
|
|
1654
516
|
return;
|
|
1655
517
|
const lastUserMsg = output.messages.filter((m) => m.info.role === "user").at(-1);
|
|
1656
518
|
if (!lastUserMsg)
|
|
1657
519
|
return;
|
|
1658
|
-
const
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
};
|
|
1662
|
-
const turnStartPath = resolvePromptPath(directory, contextDir, config.prompts.turnStart ?? join5(DEFAULTS.promptDir, DEFAULTS.turnStartFile));
|
|
1663
|
-
const turnStartRaw = readPromptFile(turnStartPath) ?? "";
|
|
1664
|
-
const turnStart = resolvePromptVariables(turnStartRaw, promptVars);
|
|
1665
|
-
const knowledgeIndex = buildKnowledgeIndexV2(directory, config.knowledge);
|
|
1666
|
-
const indexContent = knowledgeIndex.mode === "flat" ? formatKnowledgeIndex(knowledgeIndex.individualFiles) : formatDomainIndex(knowledgeIndex);
|
|
1667
|
-
const combinedContent = [turnStart, indexContent].filter(Boolean).join(`
|
|
1668
|
-
|
|
1669
|
-
`);
|
|
1670
|
-
if (combinedContent) {
|
|
1671
|
-
lastUserMsg.parts.push({
|
|
1672
|
-
id: `context-turn-start-${Date.now()}`,
|
|
1673
|
-
sessionID: lastUserMsg.info.sessionID,
|
|
1674
|
-
messageID: lastUserMsg.info.id,
|
|
1675
|
-
type: "text",
|
|
1676
|
-
text: combinedContent
|
|
1677
|
-
});
|
|
520
|
+
const isTurnEndMessage = lastUserMsg.parts.some((p) => p.type === "text" && p.text.includes("<system-reminder>") && p.text.includes("TURN END"));
|
|
521
|
+
if (isTurnEndMessage) {
|
|
522
|
+
return;
|
|
1678
523
|
}
|
|
1679
|
-
const signalPath =
|
|
1680
|
-
if (
|
|
1681
|
-
const content =
|
|
524
|
+
const signalPath = join3(directory, DEFAULTS.workCompleteFile);
|
|
525
|
+
if (existsSync3(signalPath)) {
|
|
526
|
+
const content = readFileSync2(signalPath, "utf-8");
|
|
1682
527
|
const match = content.match(/^session_id=(.*)$/m);
|
|
1683
528
|
const fileSessionId = match ? match[1].trim() : undefined;
|
|
1684
529
|
if (fileSessionId && fileSessionId !== lastUserMsg.info.sessionID) {} else {
|
|
1685
|
-
const { mtimeMs } =
|
|
530
|
+
const { mtimeMs } = statSync(signalPath);
|
|
1686
531
|
const userCreatedAt = lastUserMsg.info.time.created;
|
|
1687
532
|
if (mtimeMs >= userCreatedAt) {
|
|
1688
533
|
return;
|
|
@@ -1690,11 +535,6 @@ var plugin = async ({ directory, client }) => {
|
|
|
1690
535
|
unlinkSync(signalPath);
|
|
1691
536
|
}
|
|
1692
537
|
}
|
|
1693
|
-
const turnEndPath = resolvePromptPath(directory, contextDir, config.prompts.turnEnd ?? join5(DEFAULTS.promptDir, DEFAULTS.turnEndFile));
|
|
1694
|
-
const turnEndRaw = readPromptFile(turnEndPath);
|
|
1695
|
-
if (!turnEndRaw)
|
|
1696
|
-
return;
|
|
1697
|
-
const turnEnd = resolvePromptVariables(turnEndRaw, promptVars);
|
|
1698
538
|
const msgId = `context-turn-end-${Date.now()}`;
|
|
1699
539
|
output.messages.push({
|
|
1700
540
|
info: {
|
|
@@ -1711,9 +551,7 @@ var plugin = async ({ directory, client }) => {
|
|
|
1711
551
|
sessionID: lastUserMsg.info.sessionID,
|
|
1712
552
|
messageID: msgId,
|
|
1713
553
|
type: "text",
|
|
1714
|
-
text: `<system-reminder>
|
|
1715
|
-
${turnEnd}
|
|
1716
|
-
</system-reminder>`
|
|
554
|
+
text: `<system-reminder> TURN END. You MUST call the 'submit_turn_complete' MCP tool to finalize your work and record notes. Do not wait for user input. </system-reminder>`
|
|
1717
555
|
}
|
|
1718
556
|
]
|
|
1719
557
|
});
|