@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/dist/index.js CHANGED
@@ -1,838 +1,8 @@
1
1
  // @bun
2
2
  // src/index.ts
3
- import { existsSync as existsSync4, readFileSync as readFileSync5, statSync as statSync2, unlinkSync } from "fs";
4
- import { isAbsolute, join as join5 } from "path";
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 existsSync3, mkdirSync, readFileSync as readFileSync4, writeFileSync } from "fs";
1128
- import { join as join4 } from "path";
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.21",
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.20",
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": "docs",
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 = join4(projectDir, resolveContextDir(projectDir));
1552
- if (existsSync3(contextDir)) {
398
+ const contextDir = join2(projectDir, resolveContextDir(projectDir));
399
+ if (existsSync2(contextDir)) {
1553
400
  return false;
1554
401
  }
1555
402
  try {
1556
- const promptsDir = join4(contextDir, "prompts");
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 = join4(contextDir, "guides");
405
+ const guidesDir = join2(contextDir, "guides");
1561
406
  mkdirSync(guidesDir, { recursive: true });
1562
- writeFileSync(join4(contextDir, "config.jsonc"), DEFAULT_CONFIG, "utf-8");
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(join4(templatesDir, filename), content, "utf-8");
409
+ writeFileSync(join2(templatesDir, filename), content, "utf-8");
1567
410
  }
1568
411
  for (const [filename, content] of Object.entries(GUIDE_FILES)) {
1569
- writeFileSync(join4(guidesDir, filename), content, "utf-8");
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 readFileSync4(join4(projectDir, resolveContextDir(projectDir), ".version"), "utf-8").trim();
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(join4(contextDir, ".version"), version, "utf-8");
428
+ writeFileSync(join2(contextDir, ".version"), version, "utf-8");
1586
429
  }
1587
430
  function autoUpdateTemplates(projectDir) {
1588
- const contextDir = join4(projectDir, resolveContextDir(projectDir));
1589
- if (!existsSync3(contextDir))
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(join4(contextDir, "prompts"), { recursive: true });
1595
- mkdirSync(join4(contextDir, "templates"), { recursive: true });
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 = join4(contextDir, path);
445
+ const filePath = join2(contextDir, path);
1606
446
  try {
1607
- const existing = readFileSync4(filePath, "utf-8");
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
- function resolvePromptPath(directory, contextDir, promptPath) {
1620
- if (isAbsolute(promptPath))
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 promptVars = {
1659
- knowledgeDir: config.knowledge.dir ?? "docs",
1660
- sessionId: lastUserMsg.info.sessionID
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 = join5(directory, DEFAULTS.workCompleteFile);
1680
- if (existsSync4(signalPath)) {
1681
- const content = readFileSync5(signalPath, "utf-8");
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 } = statSync2(signalPath);
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
  });