@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/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.22",
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.21",
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
- - [ ] \`docs/daily/YYYY-MM-DD.md\` \uD30C\uC77C(\uC624\uB298 \uB0A0\uC9DC \uAE30\uC900)\uC744 \uC0DD\uC131\uD558\uAC70\uB098 \uC5C5\uB370\uC774\uD2B8\uD558\uC138\uC694.
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
- - [ ] \uD30C\uC77C \uB9E8 \uB9C8\uC9C0\uB9C9 \uC904\uC5D0 \uB2E4\uC74C\uACFC \uAC19\uC740 \uD615\uC2DD\uC73C\uB85C\uB9CC \uAE30\uB85D\uC744 \uCD94\uAC00(Append)\uD558\uC138\uC694:
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 = join4(projectDir, resolveContextDir(projectDir));
1553
- if (existsSync3(contextDir)) {
399
+ const contextDir = join2(projectDir, resolveContextDir(projectDir));
400
+ if (existsSync2(contextDir)) {
1554
401
  return false;
1555
402
  }
1556
403
  try {
1557
- const promptsDir = join4(contextDir, "prompts");
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 = join4(contextDir, "guides");
406
+ const guidesDir = join2(contextDir, "guides");
1562
407
  mkdirSync(guidesDir, { recursive: true });
1563
- writeFileSync(join4(contextDir, "config.jsonc"), DEFAULT_CONFIG, "utf-8");
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(join4(templatesDir, filename), content, "utf-8");
410
+ writeFileSync(join2(templatesDir, filename), content, "utf-8");
1568
411
  }
1569
412
  for (const [filename, content] of Object.entries(GUIDE_FILES)) {
1570
- writeFileSync(join4(guidesDir, filename), content, "utf-8");
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 readFileSync4(join4(projectDir, resolveContextDir(projectDir), ".version"), "utf-8").trim();
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(join4(contextDir, ".version"), version, "utf-8");
429
+ writeFileSync(join2(contextDir, ".version"), version, "utf-8");
1587
430
  }
1588
431
  function autoUpdateTemplates(projectDir) {
1589
- const contextDir = join4(projectDir, resolveContextDir(projectDir));
1590
- if (!existsSync3(contextDir))
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(join4(contextDir, "prompts"), { recursive: true });
1596
- mkdirSync(join4(contextDir, "templates"), { recursive: true });
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 = join4(contextDir, path);
446
+ const filePath = join2(contextDir, path);
1607
447
  try {
1608
- const existing = readFileSync4(filePath, "utf-8");
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
- function resolvePromptPath(directory, contextDir, promptPath) {
1621
- if (isAbsolute(promptPath))
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 promptVars = {
1674
- knowledgeDir: config.knowledge.dir ?? "docs",
1675
- sessionId: lastUserMsg.info.sessionID
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 } = statSync2(signalPath);
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
  });