@ksm0709/context 0.0.22 → 0.0.25
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 +10 -118
- package/dist/index.js +62 -1240
- package/dist/mcp.js +33090 -0
- package/dist/omx/index.mjs +58 -361
- 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.25",
|
|
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,10 +93,6 @@ 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
97
|
"dir": ".context/memory",
|
|
1205
98
|
"sources": ["AGENTS.md"]
|
|
@@ -1211,53 +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
|
-
\uC774 \uC9C0\uCE68\uC740 \uC5D0\uC774\uC804\uD2B8\uB97C \uC704\uD55C \uAC83\uC774\uBA70, \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC9C1\uC811\uC801\uC73C\uB85C \uB178\uCD9C\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
|
1249
|
-
\uC544\uB798 \uBA54\uB274 \uC911 \uD558\uB098\uB97C \uC120\uD0DD\uD574 \uC9C4\uD589 \uC0C1\uD669\uC5D0 \uB9DE\uAC8C \uC218\uD589\uD558\uC138\uC694.
|
|
1250
|
-
**\uBC18\uB4DC\uC2DC \uB9C1\uD06C\uB41C \uAC00\uC774\uB4DC\uB97C \uCC38\uACE0\uD558\uC5EC \uC815\uD655\uD788 \uC218\uD589\uD574\uC57C \uD569\uB2C8\uB2E4.**
|
|
1251
|
-
|
|
1252
|
-
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.
|
|
1253
|
-
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.
|
|
1254
|
-
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.
|
|
1255
|
-
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.
|
|
1256
|
-
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.
|
|
1257
|
-
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.
|
|
1258
|
-
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.
|
|
1259
|
-
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.
|
|
1260
|
-
`;
|
|
1261
107
|
var DEFAULT_ADR_TEMPLATE = `# ADR-NNN: [\uC81C\uBAA9]
|
|
1262
108
|
|
|
1263
109
|
## \uC0C1\uD0DC
|
|
@@ -1470,13 +316,14 @@ turn_id={{turnId}}
|
|
|
1470
316
|
`;
|
|
1471
317
|
var DEFAULT_DAILY_NOTE_GUIDE = `# \uB370\uC77C\uB9AC \uB178\uD2B8 \uAE30\uB85D \uAC00\uC774\uB4DC
|
|
1472
318
|
|
|
1473
|
-
- [ ] \`
|
|
319
|
+
- [ ] \`context-mcp_append_daily_note\` \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD558\uC5EC \uAE30\uB85D\uC744 \uCD94\uAC00\uD558\uC138\uC694.
|
|
1474
320
|
- [ ] **\uC8FC\uC758**: \uB370\uC77C\uB9AC \uB178\uD2B8\uC758 \uAE30\uC874 \uB0B4\uC6A9\uC740 \uC808\uB300 \uC218\uC815\uD558\uAC70\uB098 \uC0AD\uC81C\uD558\uC9C0 \uB9C8\uC138\uC694.
|
|
1475
|
-
- [ ] \
|
|
321
|
+
- [ ] \uAE30\uB85D\uC740 \uB2E4\uC74C\uACFC \uAC19\uC740 \uD615\uC2DD\uC73C\uB85C \uCD94\uAC00\uB429\uB2C8\uB2E4:
|
|
1476
322
|
\`[{{currentTimestamp}}] <\uAE30\uC5B5 \uD560 \uB0B4\uC6A9>\`
|
|
1477
323
|
- [ ] \`<\uAE30\uC5B5 \uD560 \uB0B4\uC6A9>\`\uC5D0\uB294 \uC644\uBCBD\uD55C \uCEE8\uD14D\uC2A4\uD2B8 \uC778\uACC4\uB97C \uC704\uD574 \uC624\uB298 \uC644\uB8CC\uD55C \uD575\uC2EC \uC791\uC5C5 \uC694\uC57D, \uBBF8\uD574\uACB0 \uC774\uC288(TODO), \uC911\uC694 \uBA54\uBAA8, \uC9C0\uC2DD \uB178\uD2B8 \`[[wikilink]]\` \uB4F1\uC744 \uD3EC\uD568\uD558\uC138\uC694.`;
|
|
1478
324
|
var DEFAULT_NOTE_GUIDE = `# \uC9C0\uC2DD \uB178\uD2B8 \uC791\uC131 \uBC0F \uAD00\uB9AC \uAC00\uC774\uB4DC
|
|
1479
325
|
|
|
326
|
+
- [ ] **\uB178\uD2B8 \uC0DD\uC131**: \`context-mcp_create_knowledge_note\` \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD558\uC5EC \uC0DD\uC131\uD558\uC138\uC694.
|
|
1480
327
|
- [ ] \uC81C\uD154\uCE74\uC2A4\uD150(Zettelkasten) 3\uB300 \uC6D0\uCE59 \uC900\uC218:
|
|
1481
328
|
- [ ] \uC6D0\uC790\uC131: \uD55C \uB178\uD2B8\uB2F9 \uD55C \uC8FC\uC81C
|
|
1482
329
|
- [ ] \uC5F0\uACB0: \uACE0\uB9BD\uB41C \uB178\uD2B8 \uBC29\uC9C0
|
|
@@ -1549,25 +396,21 @@ var TEMPLATE_FILES = {
|
|
|
1549
396
|
"work-complete.txt": DEFAULT_WORK_COMPLETE_TEMPLATE
|
|
1550
397
|
};
|
|
1551
398
|
function scaffoldIfNeeded(projectDir) {
|
|
1552
|
-
const contextDir =
|
|
1553
|
-
if (
|
|
399
|
+
const contextDir = join2(projectDir, resolveContextDir(projectDir));
|
|
400
|
+
if (existsSync2(contextDir)) {
|
|
1554
401
|
return false;
|
|
1555
402
|
}
|
|
1556
403
|
try {
|
|
1557
|
-
const
|
|
1558
|
-
mkdirSync(promptsDir, { recursive: true });
|
|
1559
|
-
const templatesDir = join4(contextDir, "templates");
|
|
404
|
+
const templatesDir = join2(contextDir, "templates");
|
|
1560
405
|
mkdirSync(templatesDir, { recursive: true });
|
|
1561
|
-
const guidesDir =
|
|
406
|
+
const guidesDir = join2(contextDir, "guides");
|
|
1562
407
|
mkdirSync(guidesDir, { recursive: true });
|
|
1563
|
-
writeFileSync(
|
|
1564
|
-
writeFileSync(join4(promptsDir, DEFAULTS.turnStartFile), DEFAULT_TURN_START, "utf-8");
|
|
1565
|
-
writeFileSync(join4(promptsDir, DEFAULTS.turnEndFile), DEFAULT_TURN_END, "utf-8");
|
|
408
|
+
writeFileSync(join2(contextDir, "config.jsonc"), DEFAULT_CONFIG, "utf-8");
|
|
1566
409
|
for (const [filename, content] of Object.entries(TEMPLATE_FILES)) {
|
|
1567
|
-
writeFileSync(
|
|
410
|
+
writeFileSync(join2(templatesDir, filename), content, "utf-8");
|
|
1568
411
|
}
|
|
1569
412
|
for (const [filename, content] of Object.entries(GUIDE_FILES)) {
|
|
1570
|
-
writeFileSync(
|
|
413
|
+
writeFileSync(join2(guidesDir, filename), content, "utf-8");
|
|
1571
414
|
}
|
|
1572
415
|
writeVersion(contextDir, PLUGIN_VERSION);
|
|
1573
416
|
return true;
|
|
@@ -1577,35 +420,32 @@ function scaffoldIfNeeded(projectDir) {
|
|
|
1577
420
|
}
|
|
1578
421
|
function getStoredVersion(projectDir) {
|
|
1579
422
|
try {
|
|
1580
|
-
return
|
|
423
|
+
return readFileSync(join2(projectDir, resolveContextDir(projectDir), ".version"), "utf-8").trim();
|
|
1581
424
|
} catch {
|
|
1582
425
|
return null;
|
|
1583
426
|
}
|
|
1584
427
|
}
|
|
1585
428
|
function writeVersion(contextDir, version) {
|
|
1586
|
-
writeFileSync(
|
|
429
|
+
writeFileSync(join2(contextDir, ".version"), version, "utf-8");
|
|
1587
430
|
}
|
|
1588
431
|
function autoUpdateTemplates(projectDir) {
|
|
1589
|
-
const contextDir =
|
|
1590
|
-
if (!
|
|
432
|
+
const contextDir = join2(projectDir, resolveContextDir(projectDir));
|
|
433
|
+
if (!existsSync2(contextDir))
|
|
1591
434
|
return [];
|
|
1592
435
|
const stored = getStoredVersion(projectDir);
|
|
1593
436
|
if (stored === PLUGIN_VERSION)
|
|
1594
437
|
return [];
|
|
1595
|
-
mkdirSync(
|
|
1596
|
-
mkdirSync(
|
|
1597
|
-
mkdirSync(join4(contextDir, "guides"), { recursive: true });
|
|
438
|
+
mkdirSync(join2(contextDir, "templates"), { recursive: true });
|
|
439
|
+
mkdirSync(join2(contextDir, "guides"), { recursive: true });
|
|
1598
440
|
const filesToUpdate = {
|
|
1599
|
-
[`prompts/${DEFAULTS.turnStartFile}`]: DEFAULT_TURN_START,
|
|
1600
|
-
[`prompts/${DEFAULTS.turnEndFile}`]: DEFAULT_TURN_END,
|
|
1601
441
|
...Object.fromEntries(Object.entries(TEMPLATE_FILES).map(([f, c]) => [`templates/${f}`, c])),
|
|
1602
442
|
...Object.fromEntries(Object.entries(GUIDE_FILES).map(([f, c]) => [`guides/${f}`, c]))
|
|
1603
443
|
};
|
|
1604
444
|
const updated = [];
|
|
1605
445
|
for (const [path, content] of Object.entries(filesToUpdate)) {
|
|
1606
|
-
const filePath =
|
|
446
|
+
const filePath = join2(contextDir, path);
|
|
1607
447
|
try {
|
|
1608
|
-
const existing =
|
|
448
|
+
const existing = readFileSync(filePath, "utf-8");
|
|
1609
449
|
if (existing === content)
|
|
1610
450
|
continue;
|
|
1611
451
|
} catch {}
|
|
@@ -1616,15 +456,29 @@ function autoUpdateTemplates(projectDir) {
|
|
|
1616
456
|
return updated;
|
|
1617
457
|
}
|
|
1618
458
|
|
|
459
|
+
// src/constants.ts
|
|
460
|
+
var DEFAULTS = {
|
|
461
|
+
configPath: ".context/config.jsonc",
|
|
462
|
+
knowledgeSources: ["AGENTS.md"],
|
|
463
|
+
templateDir: ".context/templates",
|
|
464
|
+
indexFilename: "INDEX.md",
|
|
465
|
+
maxDomainDepth: 2,
|
|
466
|
+
knowledgeDir: "docs",
|
|
467
|
+
guidesDir: ".context/guides",
|
|
468
|
+
workCompleteFile: ".context/.work-complete"
|
|
469
|
+
};
|
|
470
|
+
var LIMITS = {
|
|
471
|
+
maxPromptFileSize: 64 * 1024,
|
|
472
|
+
maxIndexEntries: 100,
|
|
473
|
+
maxTotalInjectionSize: 128 * 1024,
|
|
474
|
+
maxScanDepth: 3,
|
|
475
|
+
maxSummaryLength: 100,
|
|
476
|
+
maxIndexFileSize: 32 * 1024
|
|
477
|
+
};
|
|
478
|
+
|
|
1619
479
|
// src/index.ts
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
return promptPath;
|
|
1623
|
-
if (promptPath.startsWith(".context/") || promptPath.startsWith(".opencode/")) {
|
|
1624
|
-
return join5(directory, promptPath);
|
|
1625
|
-
}
|
|
1626
|
-
return join5(directory, contextDir, promptPath);
|
|
1627
|
-
}
|
|
480
|
+
var __filename2 = fileURLToPath(import.meta.url);
|
|
481
|
+
var __dirname2 = dirname(__filename2);
|
|
1628
482
|
var plugin = async ({ directory, client }) => {
|
|
1629
483
|
const scaffolded = scaffoldIfNeeded(directory);
|
|
1630
484
|
const contextDir = resolveContextDir(directory);
|
|
@@ -1648,19 +502,17 @@ var plugin = async ({ directory, client }) => {
|
|
|
1648
502
|
});
|
|
1649
503
|
}
|
|
1650
504
|
}
|
|
1651
|
-
const config = loadConfig(directory);
|
|
1652
505
|
return {
|
|
506
|
+
config: async (config) => {
|
|
507
|
+
config.mcp = config.mcp || {};
|
|
508
|
+
config.mcp["context-mcp"] = {
|
|
509
|
+
type: "local",
|
|
510
|
+
command: ["bun", join3(__dirname2, "mcp.js")]
|
|
511
|
+
};
|
|
512
|
+
},
|
|
1653
513
|
"experimental.chat.messages.transform": async (_input, output) => {
|
|
1654
514
|
if (process.env.OMX_HOOK_PLUGINS)
|
|
1655
515
|
return;
|
|
1656
|
-
let skipTurnStart = false;
|
|
1657
|
-
const agentsMdPath = join5(directory, "AGENTS.md");
|
|
1658
|
-
if (existsSync4(agentsMdPath)) {
|
|
1659
|
-
const content = readFileSync5(agentsMdPath, "utf-8");
|
|
1660
|
-
if (content.includes("<!-- context:start -->") && content.includes("<!-- context:end -->")) {
|
|
1661
|
-
skipTurnStart = true;
|
|
1662
|
-
}
|
|
1663
|
-
}
|
|
1664
516
|
if (output.messages.length === 0)
|
|
1665
517
|
return;
|
|
1666
518
|
const lastUserMsg = output.messages.filter((m) => m.info.role === "user").at(-1);
|
|
@@ -1670,36 +522,13 @@ var plugin = async ({ directory, client }) => {
|
|
|
1670
522
|
if (isTurnEndMessage) {
|
|
1671
523
|
return;
|
|
1672
524
|
}
|
|
1673
|
-
const
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
};
|
|
1677
|
-
if (!skipTurnStart) {
|
|
1678
|
-
const turnStartPath = resolvePromptPath(directory, contextDir, config.prompts.turnStart ?? join5(DEFAULTS.promptDir, DEFAULTS.turnStartFile));
|
|
1679
|
-
const turnStartRaw = readPromptFile(turnStartPath) ?? "";
|
|
1680
|
-
const turnStart = resolvePromptVariables(turnStartRaw, promptVars);
|
|
1681
|
-
const knowledgeIndex = buildKnowledgeIndexV2(directory, config.knowledge);
|
|
1682
|
-
const indexContent = knowledgeIndex.mode === "flat" ? formatKnowledgeIndex(knowledgeIndex.individualFiles) : formatDomainIndex(knowledgeIndex);
|
|
1683
|
-
const combinedContent = [turnStart, indexContent].filter(Boolean).join(`
|
|
1684
|
-
|
|
1685
|
-
`);
|
|
1686
|
-
if (combinedContent) {
|
|
1687
|
-
lastUserMsg.parts.push({
|
|
1688
|
-
id: `context-turn-start-${Date.now()}`,
|
|
1689
|
-
sessionID: lastUserMsg.info.sessionID,
|
|
1690
|
-
messageID: lastUserMsg.info.id,
|
|
1691
|
-
type: "text",
|
|
1692
|
-
text: combinedContent
|
|
1693
|
-
});
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
const signalPath = join5(directory, DEFAULTS.workCompleteFile);
|
|
1697
|
-
if (existsSync4(signalPath)) {
|
|
1698
|
-
const content = readFileSync5(signalPath, "utf-8");
|
|
525
|
+
const signalPath = join3(directory, DEFAULTS.workCompleteFile);
|
|
526
|
+
if (existsSync3(signalPath)) {
|
|
527
|
+
const content = readFileSync2(signalPath, "utf-8");
|
|
1699
528
|
const match = content.match(/^session_id=(.*)$/m);
|
|
1700
529
|
const fileSessionId = match ? match[1].trim() : undefined;
|
|
1701
530
|
if (fileSessionId && fileSessionId !== lastUserMsg.info.sessionID) {} else {
|
|
1702
|
-
const { mtimeMs } =
|
|
531
|
+
const { mtimeMs } = statSync(signalPath);
|
|
1703
532
|
const userCreatedAt = lastUserMsg.info.time.created;
|
|
1704
533
|
if (mtimeMs >= userCreatedAt) {
|
|
1705
534
|
return;
|
|
@@ -1707,11 +536,6 @@ var plugin = async ({ directory, client }) => {
|
|
|
1707
536
|
unlinkSync(signalPath);
|
|
1708
537
|
}
|
|
1709
538
|
}
|
|
1710
|
-
const turnEndPath = resolvePromptPath(directory, contextDir, config.prompts.turnEnd ?? join5(DEFAULTS.promptDir, DEFAULTS.turnEndFile));
|
|
1711
|
-
const turnEndRaw = readPromptFile(turnEndPath);
|
|
1712
|
-
if (!turnEndRaw)
|
|
1713
|
-
return;
|
|
1714
|
-
const turnEnd = resolvePromptVariables(turnEndRaw, promptVars);
|
|
1715
539
|
const msgId = `context-turn-end-${Date.now()}`;
|
|
1716
540
|
output.messages.push({
|
|
1717
541
|
info: {
|
|
@@ -1728,9 +552,7 @@ var plugin = async ({ directory, client }) => {
|
|
|
1728
552
|
sessionID: lastUserMsg.info.sessionID,
|
|
1729
553
|
messageID: msgId,
|
|
1730
554
|
type: "text",
|
|
1731
|
-
text: `<system-reminder>
|
|
1732
|
-
${turnEnd}
|
|
1733
|
-
</system-reminder>`
|
|
555
|
+
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>`
|
|
1734
556
|
}
|
|
1735
557
|
]
|
|
1736
558
|
});
|