@kairyou/agent-tools 0.3.0 → 0.5.0

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.
@@ -0,0 +1,1876 @@
1
+ #!/usr/bin/env node
2
+
3
+ // integrations/usage/core.mjs
4
+ import { pathToFileURL } from "node:url";
5
+
6
+ // integrations/usage/lib/config.mjs
7
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
8
+ import { existsSync } from "node:fs";
9
+ import { dirname, join } from "node:path";
10
+ import { homedir } from "node:os";
11
+
12
+ // node_modules/jsonc-parser/lib/esm/impl/scanner.js
13
+ function createScanner(text, ignoreTrivia = false) {
14
+ const len = text.length;
15
+ let pos = 0, value = "", tokenOffset = 0, token = 16, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0;
16
+ function scanHexDigits(count, exact) {
17
+ let digits = 0;
18
+ let value2 = 0;
19
+ while (digits < count || !exact) {
20
+ let ch = text.charCodeAt(pos);
21
+ if (ch >= 48 && ch <= 57) {
22
+ value2 = value2 * 16 + ch - 48;
23
+ } else if (ch >= 65 && ch <= 70) {
24
+ value2 = value2 * 16 + ch - 65 + 10;
25
+ } else if (ch >= 97 && ch <= 102) {
26
+ value2 = value2 * 16 + ch - 97 + 10;
27
+ } else {
28
+ break;
29
+ }
30
+ pos++;
31
+ digits++;
32
+ }
33
+ if (digits < count) {
34
+ value2 = -1;
35
+ }
36
+ return value2;
37
+ }
38
+ function setPosition(newPosition) {
39
+ pos = newPosition;
40
+ value = "";
41
+ tokenOffset = 0;
42
+ token = 16;
43
+ scanError = 0;
44
+ }
45
+ function scanNumber() {
46
+ let start = pos;
47
+ if (text.charCodeAt(pos) === 48) {
48
+ pos++;
49
+ } else {
50
+ pos++;
51
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
52
+ pos++;
53
+ }
54
+ }
55
+ if (pos < text.length && text.charCodeAt(pos) === 46) {
56
+ pos++;
57
+ if (pos < text.length && isDigit(text.charCodeAt(pos))) {
58
+ pos++;
59
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
60
+ pos++;
61
+ }
62
+ } else {
63
+ scanError = 3;
64
+ return text.substring(start, pos);
65
+ }
66
+ }
67
+ let end = pos;
68
+ if (pos < text.length && (text.charCodeAt(pos) === 69 || text.charCodeAt(pos) === 101)) {
69
+ pos++;
70
+ if (pos < text.length && text.charCodeAt(pos) === 43 || text.charCodeAt(pos) === 45) {
71
+ pos++;
72
+ }
73
+ if (pos < text.length && isDigit(text.charCodeAt(pos))) {
74
+ pos++;
75
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
76
+ pos++;
77
+ }
78
+ end = pos;
79
+ } else {
80
+ scanError = 3;
81
+ }
82
+ }
83
+ return text.substring(start, end);
84
+ }
85
+ function scanString() {
86
+ let result = "", start = pos;
87
+ while (true) {
88
+ if (pos >= len) {
89
+ result += text.substring(start, pos);
90
+ scanError = 2;
91
+ break;
92
+ }
93
+ const ch = text.charCodeAt(pos);
94
+ if (ch === 34) {
95
+ result += text.substring(start, pos);
96
+ pos++;
97
+ break;
98
+ }
99
+ if (ch === 92) {
100
+ result += text.substring(start, pos);
101
+ pos++;
102
+ if (pos >= len) {
103
+ scanError = 2;
104
+ break;
105
+ }
106
+ const ch2 = text.charCodeAt(pos++);
107
+ switch (ch2) {
108
+ case 34:
109
+ result += '"';
110
+ break;
111
+ case 92:
112
+ result += "\\";
113
+ break;
114
+ case 47:
115
+ result += "/";
116
+ break;
117
+ case 98:
118
+ result += "\b";
119
+ break;
120
+ case 102:
121
+ result += "\f";
122
+ break;
123
+ case 110:
124
+ result += "\n";
125
+ break;
126
+ case 114:
127
+ result += "\r";
128
+ break;
129
+ case 116:
130
+ result += " ";
131
+ break;
132
+ case 117:
133
+ const ch3 = scanHexDigits(4, true);
134
+ if (ch3 >= 0) {
135
+ result += String.fromCharCode(ch3);
136
+ } else {
137
+ scanError = 4;
138
+ }
139
+ break;
140
+ default:
141
+ scanError = 5;
142
+ }
143
+ start = pos;
144
+ continue;
145
+ }
146
+ if (ch >= 0 && ch <= 31) {
147
+ if (isLineBreak(ch)) {
148
+ result += text.substring(start, pos);
149
+ scanError = 2;
150
+ break;
151
+ } else {
152
+ scanError = 6;
153
+ }
154
+ }
155
+ pos++;
156
+ }
157
+ return result;
158
+ }
159
+ function scanNext() {
160
+ value = "";
161
+ scanError = 0;
162
+ tokenOffset = pos;
163
+ lineStartOffset = lineNumber;
164
+ prevTokenLineStartOffset = tokenLineStartOffset;
165
+ if (pos >= len) {
166
+ tokenOffset = len;
167
+ return token = 17;
168
+ }
169
+ let code = text.charCodeAt(pos);
170
+ if (isWhiteSpace(code)) {
171
+ do {
172
+ pos++;
173
+ value += String.fromCharCode(code);
174
+ code = text.charCodeAt(pos);
175
+ } while (isWhiteSpace(code));
176
+ return token = 15;
177
+ }
178
+ if (isLineBreak(code)) {
179
+ pos++;
180
+ value += String.fromCharCode(code);
181
+ if (code === 13 && text.charCodeAt(pos) === 10) {
182
+ pos++;
183
+ value += "\n";
184
+ }
185
+ lineNumber++;
186
+ tokenLineStartOffset = pos;
187
+ return token = 14;
188
+ }
189
+ switch (code) {
190
+ // tokens: []{}:,
191
+ case 123:
192
+ pos++;
193
+ return token = 1;
194
+ case 125:
195
+ pos++;
196
+ return token = 2;
197
+ case 91:
198
+ pos++;
199
+ return token = 3;
200
+ case 93:
201
+ pos++;
202
+ return token = 4;
203
+ case 58:
204
+ pos++;
205
+ return token = 6;
206
+ case 44:
207
+ pos++;
208
+ return token = 5;
209
+ // strings
210
+ case 34:
211
+ pos++;
212
+ value = scanString();
213
+ return token = 10;
214
+ // comments
215
+ case 47:
216
+ const start = pos - 1;
217
+ if (text.charCodeAt(pos + 1) === 47) {
218
+ pos += 2;
219
+ while (pos < len) {
220
+ if (isLineBreak(text.charCodeAt(pos))) {
221
+ break;
222
+ }
223
+ pos++;
224
+ }
225
+ value = text.substring(start, pos);
226
+ return token = 12;
227
+ }
228
+ if (text.charCodeAt(pos + 1) === 42) {
229
+ pos += 2;
230
+ const safeLength = len - 1;
231
+ let commentClosed = false;
232
+ while (pos < safeLength) {
233
+ const ch = text.charCodeAt(pos);
234
+ if (ch === 42 && text.charCodeAt(pos + 1) === 47) {
235
+ pos += 2;
236
+ commentClosed = true;
237
+ break;
238
+ }
239
+ pos++;
240
+ if (isLineBreak(ch)) {
241
+ if (ch === 13 && text.charCodeAt(pos) === 10) {
242
+ pos++;
243
+ }
244
+ lineNumber++;
245
+ tokenLineStartOffset = pos;
246
+ }
247
+ }
248
+ if (!commentClosed) {
249
+ pos++;
250
+ scanError = 1;
251
+ }
252
+ value = text.substring(start, pos);
253
+ return token = 13;
254
+ }
255
+ value += String.fromCharCode(code);
256
+ pos++;
257
+ return token = 16;
258
+ // numbers
259
+ case 45:
260
+ value += String.fromCharCode(code);
261
+ pos++;
262
+ if (pos === len || !isDigit(text.charCodeAt(pos))) {
263
+ return token = 16;
264
+ }
265
+ // found a minus, followed by a number so
266
+ // we fall through to proceed with scanning
267
+ // numbers
268
+ case 48:
269
+ case 49:
270
+ case 50:
271
+ case 51:
272
+ case 52:
273
+ case 53:
274
+ case 54:
275
+ case 55:
276
+ case 56:
277
+ case 57:
278
+ value += scanNumber();
279
+ return token = 11;
280
+ // literals and unknown symbols
281
+ default:
282
+ while (pos < len && isUnknownContentCharacter(code)) {
283
+ pos++;
284
+ code = text.charCodeAt(pos);
285
+ }
286
+ if (tokenOffset !== pos) {
287
+ value = text.substring(tokenOffset, pos);
288
+ switch (value) {
289
+ case "true":
290
+ return token = 8;
291
+ case "false":
292
+ return token = 9;
293
+ case "null":
294
+ return token = 7;
295
+ }
296
+ return token = 16;
297
+ }
298
+ value += String.fromCharCode(code);
299
+ pos++;
300
+ return token = 16;
301
+ }
302
+ }
303
+ function isUnknownContentCharacter(code) {
304
+ if (isWhiteSpace(code) || isLineBreak(code)) {
305
+ return false;
306
+ }
307
+ switch (code) {
308
+ case 125:
309
+ case 93:
310
+ case 123:
311
+ case 91:
312
+ case 34:
313
+ case 58:
314
+ case 44:
315
+ case 47:
316
+ return false;
317
+ }
318
+ return true;
319
+ }
320
+ function scanNextNonTrivia() {
321
+ let result;
322
+ do {
323
+ result = scanNext();
324
+ } while (result >= 12 && result <= 15);
325
+ return result;
326
+ }
327
+ return {
328
+ setPosition,
329
+ getPosition: () => pos,
330
+ scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
331
+ getToken: () => token,
332
+ getTokenValue: () => value,
333
+ getTokenOffset: () => tokenOffset,
334
+ getTokenLength: () => pos - tokenOffset,
335
+ getTokenStartLine: () => lineStartOffset,
336
+ getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,
337
+ getTokenError: () => scanError
338
+ };
339
+ }
340
+ function isWhiteSpace(ch) {
341
+ return ch === 32 || ch === 9;
342
+ }
343
+ function isLineBreak(ch) {
344
+ return ch === 10 || ch === 13;
345
+ }
346
+ function isDigit(ch) {
347
+ return ch >= 48 && ch <= 57;
348
+ }
349
+ var CharacterCodes;
350
+ (function(CharacterCodes2) {
351
+ CharacterCodes2[CharacterCodes2["lineFeed"] = 10] = "lineFeed";
352
+ CharacterCodes2[CharacterCodes2["carriageReturn"] = 13] = "carriageReturn";
353
+ CharacterCodes2[CharacterCodes2["space"] = 32] = "space";
354
+ CharacterCodes2[CharacterCodes2["_0"] = 48] = "_0";
355
+ CharacterCodes2[CharacterCodes2["_1"] = 49] = "_1";
356
+ CharacterCodes2[CharacterCodes2["_2"] = 50] = "_2";
357
+ CharacterCodes2[CharacterCodes2["_3"] = 51] = "_3";
358
+ CharacterCodes2[CharacterCodes2["_4"] = 52] = "_4";
359
+ CharacterCodes2[CharacterCodes2["_5"] = 53] = "_5";
360
+ CharacterCodes2[CharacterCodes2["_6"] = 54] = "_6";
361
+ CharacterCodes2[CharacterCodes2["_7"] = 55] = "_7";
362
+ CharacterCodes2[CharacterCodes2["_8"] = 56] = "_8";
363
+ CharacterCodes2[CharacterCodes2["_9"] = 57] = "_9";
364
+ CharacterCodes2[CharacterCodes2["a"] = 97] = "a";
365
+ CharacterCodes2[CharacterCodes2["b"] = 98] = "b";
366
+ CharacterCodes2[CharacterCodes2["c"] = 99] = "c";
367
+ CharacterCodes2[CharacterCodes2["d"] = 100] = "d";
368
+ CharacterCodes2[CharacterCodes2["e"] = 101] = "e";
369
+ CharacterCodes2[CharacterCodes2["f"] = 102] = "f";
370
+ CharacterCodes2[CharacterCodes2["g"] = 103] = "g";
371
+ CharacterCodes2[CharacterCodes2["h"] = 104] = "h";
372
+ CharacterCodes2[CharacterCodes2["i"] = 105] = "i";
373
+ CharacterCodes2[CharacterCodes2["j"] = 106] = "j";
374
+ CharacterCodes2[CharacterCodes2["k"] = 107] = "k";
375
+ CharacterCodes2[CharacterCodes2["l"] = 108] = "l";
376
+ CharacterCodes2[CharacterCodes2["m"] = 109] = "m";
377
+ CharacterCodes2[CharacterCodes2["n"] = 110] = "n";
378
+ CharacterCodes2[CharacterCodes2["o"] = 111] = "o";
379
+ CharacterCodes2[CharacterCodes2["p"] = 112] = "p";
380
+ CharacterCodes2[CharacterCodes2["q"] = 113] = "q";
381
+ CharacterCodes2[CharacterCodes2["r"] = 114] = "r";
382
+ CharacterCodes2[CharacterCodes2["s"] = 115] = "s";
383
+ CharacterCodes2[CharacterCodes2["t"] = 116] = "t";
384
+ CharacterCodes2[CharacterCodes2["u"] = 117] = "u";
385
+ CharacterCodes2[CharacterCodes2["v"] = 118] = "v";
386
+ CharacterCodes2[CharacterCodes2["w"] = 119] = "w";
387
+ CharacterCodes2[CharacterCodes2["x"] = 120] = "x";
388
+ CharacterCodes2[CharacterCodes2["y"] = 121] = "y";
389
+ CharacterCodes2[CharacterCodes2["z"] = 122] = "z";
390
+ CharacterCodes2[CharacterCodes2["A"] = 65] = "A";
391
+ CharacterCodes2[CharacterCodes2["B"] = 66] = "B";
392
+ CharacterCodes2[CharacterCodes2["C"] = 67] = "C";
393
+ CharacterCodes2[CharacterCodes2["D"] = 68] = "D";
394
+ CharacterCodes2[CharacterCodes2["E"] = 69] = "E";
395
+ CharacterCodes2[CharacterCodes2["F"] = 70] = "F";
396
+ CharacterCodes2[CharacterCodes2["G"] = 71] = "G";
397
+ CharacterCodes2[CharacterCodes2["H"] = 72] = "H";
398
+ CharacterCodes2[CharacterCodes2["I"] = 73] = "I";
399
+ CharacterCodes2[CharacterCodes2["J"] = 74] = "J";
400
+ CharacterCodes2[CharacterCodes2["K"] = 75] = "K";
401
+ CharacterCodes2[CharacterCodes2["L"] = 76] = "L";
402
+ CharacterCodes2[CharacterCodes2["M"] = 77] = "M";
403
+ CharacterCodes2[CharacterCodes2["N"] = 78] = "N";
404
+ CharacterCodes2[CharacterCodes2["O"] = 79] = "O";
405
+ CharacterCodes2[CharacterCodes2["P"] = 80] = "P";
406
+ CharacterCodes2[CharacterCodes2["Q"] = 81] = "Q";
407
+ CharacterCodes2[CharacterCodes2["R"] = 82] = "R";
408
+ CharacterCodes2[CharacterCodes2["S"] = 83] = "S";
409
+ CharacterCodes2[CharacterCodes2["T"] = 84] = "T";
410
+ CharacterCodes2[CharacterCodes2["U"] = 85] = "U";
411
+ CharacterCodes2[CharacterCodes2["V"] = 86] = "V";
412
+ CharacterCodes2[CharacterCodes2["W"] = 87] = "W";
413
+ CharacterCodes2[CharacterCodes2["X"] = 88] = "X";
414
+ CharacterCodes2[CharacterCodes2["Y"] = 89] = "Y";
415
+ CharacterCodes2[CharacterCodes2["Z"] = 90] = "Z";
416
+ CharacterCodes2[CharacterCodes2["asterisk"] = 42] = "asterisk";
417
+ CharacterCodes2[CharacterCodes2["backslash"] = 92] = "backslash";
418
+ CharacterCodes2[CharacterCodes2["closeBrace"] = 125] = "closeBrace";
419
+ CharacterCodes2[CharacterCodes2["closeBracket"] = 93] = "closeBracket";
420
+ CharacterCodes2[CharacterCodes2["colon"] = 58] = "colon";
421
+ CharacterCodes2[CharacterCodes2["comma"] = 44] = "comma";
422
+ CharacterCodes2[CharacterCodes2["dot"] = 46] = "dot";
423
+ CharacterCodes2[CharacterCodes2["doubleQuote"] = 34] = "doubleQuote";
424
+ CharacterCodes2[CharacterCodes2["minus"] = 45] = "minus";
425
+ CharacterCodes2[CharacterCodes2["openBrace"] = 123] = "openBrace";
426
+ CharacterCodes2[CharacterCodes2["openBracket"] = 91] = "openBracket";
427
+ CharacterCodes2[CharacterCodes2["plus"] = 43] = "plus";
428
+ CharacterCodes2[CharacterCodes2["slash"] = 47] = "slash";
429
+ CharacterCodes2[CharacterCodes2["formFeed"] = 12] = "formFeed";
430
+ CharacterCodes2[CharacterCodes2["tab"] = 9] = "tab";
431
+ })(CharacterCodes || (CharacterCodes = {}));
432
+
433
+ // node_modules/jsonc-parser/lib/esm/impl/string-intern.js
434
+ var cachedSpaces = new Array(20).fill(0).map((_, index) => {
435
+ return " ".repeat(index);
436
+ });
437
+ var maxCachedValues = 200;
438
+ var cachedBreakLinesWithSpaces = {
439
+ " ": {
440
+ "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
441
+ return "\n" + " ".repeat(index);
442
+ }),
443
+ "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
444
+ return "\r" + " ".repeat(index);
445
+ }),
446
+ "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
447
+ return "\r\n" + " ".repeat(index);
448
+ })
449
+ },
450
+ " ": {
451
+ "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
452
+ return "\n" + " ".repeat(index);
453
+ }),
454
+ "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
455
+ return "\r" + " ".repeat(index);
456
+ }),
457
+ "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
458
+ return "\r\n" + " ".repeat(index);
459
+ })
460
+ }
461
+ };
462
+
463
+ // node_modules/jsonc-parser/lib/esm/impl/parser.js
464
+ var ParseOptions;
465
+ (function(ParseOptions2) {
466
+ ParseOptions2.DEFAULT = {
467
+ allowTrailingComma: false
468
+ };
469
+ })(ParseOptions || (ParseOptions = {}));
470
+ function parse(text, errors = [], options = ParseOptions.DEFAULT) {
471
+ let currentProperty = null;
472
+ let currentParent = [];
473
+ const previousParents = [];
474
+ function onValue(value) {
475
+ if (Array.isArray(currentParent)) {
476
+ currentParent.push(value);
477
+ } else if (currentProperty !== null) {
478
+ currentParent[currentProperty] = value;
479
+ }
480
+ }
481
+ const visitor = {
482
+ onObjectBegin: () => {
483
+ const object = {};
484
+ onValue(object);
485
+ previousParents.push(currentParent);
486
+ currentParent = object;
487
+ currentProperty = null;
488
+ },
489
+ onObjectProperty: (name) => {
490
+ currentProperty = name;
491
+ },
492
+ onObjectEnd: () => {
493
+ currentParent = previousParents.pop();
494
+ },
495
+ onArrayBegin: () => {
496
+ const array = [];
497
+ onValue(array);
498
+ previousParents.push(currentParent);
499
+ currentParent = array;
500
+ currentProperty = null;
501
+ },
502
+ onArrayEnd: () => {
503
+ currentParent = previousParents.pop();
504
+ },
505
+ onLiteralValue: onValue,
506
+ onError: (error, offset, length) => {
507
+ errors.push({ error, offset, length });
508
+ }
509
+ };
510
+ visit(text, visitor, options);
511
+ return currentParent[0];
512
+ }
513
+ function visit(text, visitor, options = ParseOptions.DEFAULT) {
514
+ const _scanner = createScanner(text, false);
515
+ const _jsonPath = [];
516
+ let suppressedCallbacks = 0;
517
+ function toNoArgVisit(visitFunction) {
518
+ return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
519
+ }
520
+ function toOneArgVisit(visitFunction) {
521
+ return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
522
+ }
523
+ function toOneArgVisitWithPath(visitFunction) {
524
+ return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;
525
+ }
526
+ function toBeginVisit(visitFunction) {
527
+ return visitFunction ? () => {
528
+ if (suppressedCallbacks > 0) {
529
+ suppressedCallbacks++;
530
+ } else {
531
+ let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());
532
+ if (cbReturn === false) {
533
+ suppressedCallbacks = 1;
534
+ }
535
+ }
536
+ } : () => true;
537
+ }
538
+ function toEndVisit(visitFunction) {
539
+ return visitFunction ? () => {
540
+ if (suppressedCallbacks > 0) {
541
+ suppressedCallbacks--;
542
+ }
543
+ if (suppressedCallbacks === 0) {
544
+ visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());
545
+ }
546
+ } : () => true;
547
+ }
548
+ 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);
549
+ const disallowComments = options && options.disallowComments;
550
+ const allowTrailingComma = options && options.allowTrailingComma;
551
+ function scanNext() {
552
+ while (true) {
553
+ const token = _scanner.scan();
554
+ switch (_scanner.getTokenError()) {
555
+ case 4:
556
+ handleError(
557
+ 14
558
+ /* ParseErrorCode.InvalidUnicode */
559
+ );
560
+ break;
561
+ case 5:
562
+ handleError(
563
+ 15
564
+ /* ParseErrorCode.InvalidEscapeCharacter */
565
+ );
566
+ break;
567
+ case 3:
568
+ handleError(
569
+ 13
570
+ /* ParseErrorCode.UnexpectedEndOfNumber */
571
+ );
572
+ break;
573
+ case 1:
574
+ if (!disallowComments) {
575
+ handleError(
576
+ 11
577
+ /* ParseErrorCode.UnexpectedEndOfComment */
578
+ );
579
+ }
580
+ break;
581
+ case 2:
582
+ handleError(
583
+ 12
584
+ /* ParseErrorCode.UnexpectedEndOfString */
585
+ );
586
+ break;
587
+ case 6:
588
+ handleError(
589
+ 16
590
+ /* ParseErrorCode.InvalidCharacter */
591
+ );
592
+ break;
593
+ }
594
+ switch (token) {
595
+ case 12:
596
+ case 13:
597
+ if (disallowComments) {
598
+ handleError(
599
+ 10
600
+ /* ParseErrorCode.InvalidCommentToken */
601
+ );
602
+ } else {
603
+ onComment();
604
+ }
605
+ break;
606
+ case 16:
607
+ handleError(
608
+ 1
609
+ /* ParseErrorCode.InvalidSymbol */
610
+ );
611
+ break;
612
+ case 15:
613
+ case 14:
614
+ break;
615
+ default:
616
+ return token;
617
+ }
618
+ }
619
+ }
620
+ function handleError(error, skipUntilAfter = [], skipUntil = []) {
621
+ onError(error);
622
+ if (skipUntilAfter.length + skipUntil.length > 0) {
623
+ let token = _scanner.getToken();
624
+ while (token !== 17) {
625
+ if (skipUntilAfter.indexOf(token) !== -1) {
626
+ scanNext();
627
+ break;
628
+ } else if (skipUntil.indexOf(token) !== -1) {
629
+ break;
630
+ }
631
+ token = scanNext();
632
+ }
633
+ }
634
+ }
635
+ function parseString(isValue) {
636
+ const value = _scanner.getTokenValue();
637
+ if (isValue) {
638
+ onLiteralValue(value);
639
+ } else {
640
+ onObjectProperty(value);
641
+ _jsonPath.push(value);
642
+ }
643
+ scanNext();
644
+ return true;
645
+ }
646
+ function parseLiteral() {
647
+ switch (_scanner.getToken()) {
648
+ case 11:
649
+ const tokenValue = _scanner.getTokenValue();
650
+ let value = Number(tokenValue);
651
+ if (isNaN(value)) {
652
+ handleError(
653
+ 2
654
+ /* ParseErrorCode.InvalidNumberFormat */
655
+ );
656
+ value = 0;
657
+ }
658
+ onLiteralValue(value);
659
+ break;
660
+ case 7:
661
+ onLiteralValue(null);
662
+ break;
663
+ case 8:
664
+ onLiteralValue(true);
665
+ break;
666
+ case 9:
667
+ onLiteralValue(false);
668
+ break;
669
+ default:
670
+ return false;
671
+ }
672
+ scanNext();
673
+ return true;
674
+ }
675
+ function parseProperty() {
676
+ if (_scanner.getToken() !== 10) {
677
+ handleError(3, [], [
678
+ 2,
679
+ 5
680
+ /* SyntaxKind.CommaToken */
681
+ ]);
682
+ return false;
683
+ }
684
+ parseString(false);
685
+ if (_scanner.getToken() === 6) {
686
+ onSeparator(":");
687
+ scanNext();
688
+ if (!parseValue()) {
689
+ handleError(4, [], [
690
+ 2,
691
+ 5
692
+ /* SyntaxKind.CommaToken */
693
+ ]);
694
+ }
695
+ } else {
696
+ handleError(5, [], [
697
+ 2,
698
+ 5
699
+ /* SyntaxKind.CommaToken */
700
+ ]);
701
+ }
702
+ _jsonPath.pop();
703
+ return true;
704
+ }
705
+ function parseObject() {
706
+ onObjectBegin();
707
+ scanNext();
708
+ let needsComma = false;
709
+ while (_scanner.getToken() !== 2 && _scanner.getToken() !== 17) {
710
+ if (_scanner.getToken() === 5) {
711
+ if (!needsComma) {
712
+ handleError(4, [], []);
713
+ }
714
+ onSeparator(",");
715
+ scanNext();
716
+ if (_scanner.getToken() === 2 && allowTrailingComma) {
717
+ break;
718
+ }
719
+ } else if (needsComma) {
720
+ handleError(6, [], []);
721
+ }
722
+ if (!parseProperty()) {
723
+ handleError(4, [], [
724
+ 2,
725
+ 5
726
+ /* SyntaxKind.CommaToken */
727
+ ]);
728
+ }
729
+ needsComma = true;
730
+ }
731
+ onObjectEnd();
732
+ if (_scanner.getToken() !== 2) {
733
+ handleError(7, [
734
+ 2
735
+ /* SyntaxKind.CloseBraceToken */
736
+ ], []);
737
+ } else {
738
+ scanNext();
739
+ }
740
+ return true;
741
+ }
742
+ function parseArray() {
743
+ onArrayBegin();
744
+ scanNext();
745
+ let isFirstElement = true;
746
+ let needsComma = false;
747
+ while (_scanner.getToken() !== 4 && _scanner.getToken() !== 17) {
748
+ if (_scanner.getToken() === 5) {
749
+ if (!needsComma) {
750
+ handleError(4, [], []);
751
+ }
752
+ onSeparator(",");
753
+ scanNext();
754
+ if (_scanner.getToken() === 4 && allowTrailingComma) {
755
+ break;
756
+ }
757
+ } else if (needsComma) {
758
+ handleError(6, [], []);
759
+ }
760
+ if (isFirstElement) {
761
+ _jsonPath.push(0);
762
+ isFirstElement = false;
763
+ } else {
764
+ _jsonPath[_jsonPath.length - 1]++;
765
+ }
766
+ if (!parseValue()) {
767
+ handleError(4, [], [
768
+ 4,
769
+ 5
770
+ /* SyntaxKind.CommaToken */
771
+ ]);
772
+ }
773
+ needsComma = true;
774
+ }
775
+ onArrayEnd();
776
+ if (!isFirstElement) {
777
+ _jsonPath.pop();
778
+ }
779
+ if (_scanner.getToken() !== 4) {
780
+ handleError(8, [
781
+ 4
782
+ /* SyntaxKind.CloseBracketToken */
783
+ ], []);
784
+ } else {
785
+ scanNext();
786
+ }
787
+ return true;
788
+ }
789
+ function parseValue() {
790
+ switch (_scanner.getToken()) {
791
+ case 3:
792
+ return parseArray();
793
+ case 1:
794
+ return parseObject();
795
+ case 10:
796
+ return parseString(true);
797
+ default:
798
+ return parseLiteral();
799
+ }
800
+ }
801
+ scanNext();
802
+ if (_scanner.getToken() === 17) {
803
+ if (options.allowEmptyContent) {
804
+ return true;
805
+ }
806
+ handleError(4, [], []);
807
+ return false;
808
+ }
809
+ if (!parseValue()) {
810
+ handleError(4, [], []);
811
+ return false;
812
+ }
813
+ if (_scanner.getToken() !== 17) {
814
+ handleError(9, [], []);
815
+ }
816
+ return true;
817
+ }
818
+
819
+ // node_modules/jsonc-parser/lib/esm/main.js
820
+ var ScanError;
821
+ (function(ScanError2) {
822
+ ScanError2[ScanError2["None"] = 0] = "None";
823
+ ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
824
+ ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
825
+ ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
826
+ ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
827
+ ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
828
+ ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
829
+ })(ScanError || (ScanError = {}));
830
+ var SyntaxKind;
831
+ (function(SyntaxKind2) {
832
+ SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
833
+ SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
834
+ SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
835
+ SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
836
+ SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
837
+ SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
838
+ SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
839
+ SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
840
+ SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
841
+ SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
842
+ SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
843
+ SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
844
+ SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
845
+ SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
846
+ SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
847
+ SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
848
+ SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
849
+ })(SyntaxKind || (SyntaxKind = {}));
850
+ var parse2 = parse;
851
+ var ParseErrorCode;
852
+ (function(ParseErrorCode2) {
853
+ ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
854
+ ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
855
+ ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
856
+ ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
857
+ ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
858
+ ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
859
+ ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
860
+ ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
861
+ ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
862
+ ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
863
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
864
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
865
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
866
+ ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
867
+ ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
868
+ ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
869
+ })(ParseErrorCode || (ParseErrorCode = {}));
870
+
871
+ // integrations/usage/lib/config.mjs
872
+ var CODEX_HOME = process.env.CODEX_HOME || join(homedir(), ".codex");
873
+ var AGENT_TOOLS_HOME = process.env.AGENT_TOOLS_HOME || join(homedir(), ".agent-tools");
874
+ var AUTH_PATH = join(CODEX_HOME, "auth.json");
875
+ var CODEX_CONFIG_PATH = join(CODEX_HOME, "config.toml");
876
+ var AGENT_CONFIG_PATH = join(AGENT_TOOLS_HOME, "config.jsonc");
877
+ var DEBUG_PATH = join(AGENT_TOOLS_HOME, "logs", "usage-debug.log");
878
+ var ROUTE_CACHE_PATH = join(AGENT_TOOLS_HOME, "cache", "usage-routes.json");
879
+ var SNAPSHOT_PATH = join(AGENT_TOOLS_HOME, "cache", "usage-snapshot.json");
880
+ var REFRESH_STATE_PATH = join(AGENT_TOOLS_HOME, "cache", "usage-refresh-state.json");
881
+ var DEFAULT_USAGE_DAYS = 30;
882
+ var MAX_USAGE_DAYS = 90;
883
+ var DEFAULT_NEW_API_QUOTA_SCALE = 5e5;
884
+ async function readJson(path) {
885
+ return JSON.parse(await readFile(path, "utf8"));
886
+ }
887
+ async function readTextIfExists(path) {
888
+ if (!existsSync(path)) return "";
889
+ return readFile(path, "utf8");
890
+ }
891
+ var agentConfigCache;
892
+ async function agentConfig() {
893
+ if (agentConfigCache) return agentConfigCache;
894
+ try {
895
+ const raw = await readTextIfExists(AGENT_CONFIG_PATH);
896
+ if (!raw.trim()) {
897
+ agentConfigCache = {};
898
+ return agentConfigCache;
899
+ }
900
+ const errors = [];
901
+ const parsed = parse2(raw.replace(/^\uFEFF/, ""), errors, { allowTrailingComma: true });
902
+ agentConfigCache = errors.length === 0 && parsed?.providerUsage || {};
903
+ } catch {
904
+ agentConfigCache = {};
905
+ }
906
+ return agentConfigCache;
907
+ }
908
+ async function debugLog(event) {
909
+ const config = await agentConfig();
910
+ if (process.env.PROVIDER_USAGE_DEBUG !== "1" && config.debug !== true) return;
911
+ await mkdir(dirname(DEBUG_PATH), { recursive: true });
912
+ const line = JSON.stringify({
913
+ at: (/* @__PURE__ */ new Date()).toISOString(),
914
+ ...event
915
+ });
916
+ await writeFile(DEBUG_PATH, `${line}
917
+ `, { flag: "a" });
918
+ }
919
+ async function providerUsageDays() {
920
+ const config = await agentConfig();
921
+ const value = Number(process.env.PROVIDER_USAGE_DAYS || config.days || DEFAULT_USAGE_DAYS);
922
+ if (!Number.isInteger(value) || value <= 0 || value > MAX_USAGE_DAYS) return DEFAULT_USAGE_DAYS;
923
+ return value;
924
+ }
925
+ async function usagePreset() {
926
+ const config = await agentConfig();
927
+ return String(process.env.PROVIDER_USAGE_PRESET || config.preset || "auto").toLowerCase();
928
+ }
929
+ async function panelUserId() {
930
+ const config = await agentConfig();
931
+ const raw = process.env.PROVIDER_USAGE_USER_ID || config.userId || "";
932
+ const parsed = Number.parseInt(String(raw), 10);
933
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
934
+ }
935
+ async function panelUserHeaders() {
936
+ const userId = await panelUserId();
937
+ if (!userId) return {};
938
+ const value = String(userId);
939
+ return {
940
+ "New-API-User": value,
941
+ "Veloera-User": value,
942
+ "voapi-user": value,
943
+ "User-id": value,
944
+ "X-User-Id": value,
945
+ "Rix-Api-User": value,
946
+ "neo-api-user": value
947
+ };
948
+ }
949
+ async function newApiQuotaScale() {
950
+ const config = await agentConfig();
951
+ const scale = Number(config.newApiQuotaScale || DEFAULT_NEW_API_QUOTA_SCALE);
952
+ return Number.isFinite(scale) && scale > 0 ? scale : 0;
953
+ }
954
+
955
+ // integrations/usage/lib/urls.mjs
956
+ function isOfficialBaseUrl(baseUrl) {
957
+ if (!baseUrl) return true;
958
+ const clean = baseUrl.replace(/\/+$/, "");
959
+ return [
960
+ "https://api.openai.com",
961
+ "https://api.openai.com/v1",
962
+ "https://api.anthropic.com",
963
+ "https://api.anthropic.com/v1"
964
+ ].includes(clean);
965
+ }
966
+ function cleanBaseUrl(baseUrl) {
967
+ return String(baseUrl || "").replace(/\/+$/, "");
968
+ }
969
+ function serviceRoot(baseUrl) {
970
+ const clean = cleanBaseUrl(baseUrl);
971
+ return clean.endsWith("/v1") ? clean.slice(0, -3) : clean;
972
+ }
973
+ function usageRouteCacheKey(baseUrl) {
974
+ try {
975
+ const url = new URL(cleanBaseUrl(baseUrl));
976
+ url.hash = "";
977
+ url.search = "";
978
+ url.pathname = url.pathname.replace(/\/+$/, "").replace(/\/api\/v1$/i, "").replace(/\/v1$/i, "");
979
+ return url.toString().replace(/\/$/, "");
980
+ } catch {
981
+ return serviceRoot(baseUrl);
982
+ }
983
+ }
984
+ function joinUrl(baseUrl, path) {
985
+ return `${cleanBaseUrl(baseUrl)}${path.startsWith("/") ? path : `/${path}`}`;
986
+ }
987
+ function hostIncludes(baseUrl, value) {
988
+ try {
989
+ return new URL(baseUrl).hostname.toLowerCase().includes(value);
990
+ } catch {
991
+ return false;
992
+ }
993
+ }
994
+
995
+ // integrations/usage/lib/cache.mjs
996
+ import { writeFile as writeFile2, mkdir as mkdir2 } from "node:fs/promises";
997
+ import { dirname as dirname2 } from "node:path";
998
+ var ROUTE_CACHE_VERSION = 1;
999
+ var SNAPSHOT_VERSION = 1;
1000
+ var REFRESH_STATE_VERSION = 1;
1001
+ async function readRouteCache() {
1002
+ try {
1003
+ const raw = await readTextIfExists(ROUTE_CACHE_PATH);
1004
+ if (!raw.trim()) return { version: ROUTE_CACHE_VERSION, routes: {} };
1005
+ const parsed = JSON.parse(raw);
1006
+ return {
1007
+ version: ROUTE_CACHE_VERSION,
1008
+ routes: parsed?.routes && typeof parsed.routes === "object" ? parsed.routes : {}
1009
+ };
1010
+ } catch {
1011
+ return { version: ROUTE_CACHE_VERSION, routes: {} };
1012
+ }
1013
+ }
1014
+ async function rememberUsageRoute(context, route, result) {
1015
+ try {
1016
+ const cache = await readRouteCache();
1017
+ const key = usageRouteCacheKey(context.baseUrl);
1018
+ cache.routes[key] = {
1019
+ route: route.id,
1020
+ path: route.path,
1021
+ source: result.source,
1022
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1023
+ };
1024
+ await mkdir2(dirname2(ROUTE_CACHE_PATH), { recursive: true });
1025
+ await writeFile2(ROUTE_CACHE_PATH, `${JSON.stringify(cache, null, 2)}
1026
+ `);
1027
+ } catch (error) {
1028
+ await debugLog({ source: "route-cache", error: error.message });
1029
+ }
1030
+ }
1031
+ async function readSnapshotCache() {
1032
+ try {
1033
+ const raw = await readTextIfExists(SNAPSHOT_PATH);
1034
+ if (!raw.trim()) return { version: SNAPSHOT_VERSION, items: {} };
1035
+ const parsed = JSON.parse(raw);
1036
+ return {
1037
+ version: SNAPSHOT_VERSION,
1038
+ items: parsed?.items && typeof parsed.items === "object" ? parsed.items : {}
1039
+ };
1040
+ } catch {
1041
+ return { version: SNAPSHOT_VERSION, items: {} };
1042
+ }
1043
+ }
1044
+ async function rememberUsageSnapshot(context, result) {
1045
+ if (!result?.text) return;
1046
+ try {
1047
+ const cache = await readSnapshotCache();
1048
+ const key = usageRouteCacheKey(context.baseUrl);
1049
+ cache.items[key] = {
1050
+ text: result.text,
1051
+ source: result.source,
1052
+ baseUrl: context.baseUrl,
1053
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1054
+ };
1055
+ await mkdir2(dirname2(SNAPSHOT_PATH), { recursive: true });
1056
+ await writeFile2(SNAPSHOT_PATH, `${JSON.stringify(cache, null, 2)}
1057
+ `);
1058
+ } catch (error) {
1059
+ await debugLog({ source: "snapshot-cache", error: error.message });
1060
+ }
1061
+ }
1062
+ async function readRefreshState() {
1063
+ try {
1064
+ const raw = await readTextIfExists(REFRESH_STATE_PATH);
1065
+ if (!raw.trim()) return { version: REFRESH_STATE_VERSION, items: {} };
1066
+ const parsed = JSON.parse(raw);
1067
+ return {
1068
+ version: REFRESH_STATE_VERSION,
1069
+ items: parsed?.items && typeof parsed.items === "object" ? parsed.items : {}
1070
+ };
1071
+ } catch {
1072
+ return { version: REFRESH_STATE_VERSION, items: {} };
1073
+ }
1074
+ }
1075
+ async function rememberRefreshState(context, patch) {
1076
+ try {
1077
+ const state = await readRefreshState();
1078
+ const key = usageRouteCacheKey(context.baseUrl);
1079
+ state.items[key] = {
1080
+ ...state.items[key] || {},
1081
+ ...patch,
1082
+ baseUrl: context.baseUrl
1083
+ };
1084
+ await mkdir2(dirname2(REFRESH_STATE_PATH), { recursive: true });
1085
+ await writeFile2(REFRESH_STATE_PATH, `${JSON.stringify(state, null, 2)}
1086
+ `);
1087
+ } catch (error) {
1088
+ await debugLog({ source: "refresh-state", error: error.message });
1089
+ }
1090
+ }
1091
+
1092
+ // integrations/usage/lib/http.mjs
1093
+ import { createContext, runInContext } from "node:vm";
1094
+ var REQUEST_TIMEOUT_MS = 5e3;
1095
+ var SHIELD_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36";
1096
+ function shortPreview(text) {
1097
+ return String(text || "").replace(/\s+/g, " ").trim().slice(0, 220);
1098
+ }
1099
+ function isShieldChallenge(contentType, text) {
1100
+ const normalizedType = String(contentType || "").toLowerCase();
1101
+ return normalizedType.includes("text/html") && /var\s+arg1\s*=|acw_sc__v2|cdn_sec_tc|<script/i.test(text) || /var\s+arg1\s*=/.test(text);
1102
+ }
1103
+ function parseChallengeArg1(html) {
1104
+ const match = String(html).match(/var\s+arg1\s*=\s*['"]([0-9a-fA-F]+)['"]/);
1105
+ return match?.[1]?.toUpperCase() || "";
1106
+ }
1107
+ function parseChallengeMapping(html) {
1108
+ const match = String(html).match(/for\(var m=\[([^\]]+)\],p=L\(0x115\)/);
1109
+ if (!match?.[1]) return null;
1110
+ const values = match[1].split(",").map((raw) => {
1111
+ const value = raw.trim().toLowerCase();
1112
+ if (!value) return Number.NaN;
1113
+ return value.startsWith("0x") ? Number.parseInt(value.slice(2), 16) : Number.parseInt(value, 10);
1114
+ });
1115
+ return values.some((value) => Number.isNaN(value)) ? null : values;
1116
+ }
1117
+ function parseChallengeXorSeed(html) {
1118
+ const text = String(html);
1119
+ const fnStart = text.indexOf("function a0i()");
1120
+ const bStart = text.indexOf("function b(");
1121
+ const rotateStart = text.indexOf("(function(a,c){");
1122
+ const rotateEnd = text.indexOf("),!(function", rotateStart);
1123
+ if (fnStart < 0 || bStart < 0 || bStart <= fnStart || rotateStart < 0 || rotateEnd < 0) {
1124
+ return "";
1125
+ }
1126
+ const helperCode = text.slice(fnStart, bStart);
1127
+ const rotateCode = `${text.slice(rotateStart, rotateEnd + 1)})`;
1128
+ try {
1129
+ const sandbox = { decodeURIComponent };
1130
+ createContext(sandbox);
1131
+ runInContext(helperCode, sandbox, { timeout: 100 });
1132
+ runInContext(rotateCode, sandbox, { timeout: 100 });
1133
+ const decoder = sandbox.a0j;
1134
+ if (typeof decoder !== "function") return "";
1135
+ const seed = decoder(277);
1136
+ return typeof seed === "string" && /^[0-9a-f]+$/i.test(seed) ? seed : "";
1137
+ } catch {
1138
+ return "";
1139
+ }
1140
+ }
1141
+ function solveNewApiAcwScV2(html) {
1142
+ const arg1 = parseChallengeArg1(html);
1143
+ const mapping = parseChallengeMapping(html);
1144
+ const xorSeed = parseChallengeXorSeed(html);
1145
+ if (!arg1 || !mapping || !xorSeed) return "";
1146
+ const reordered = [];
1147
+ for (let i = 0; i < arg1.length; i += 1) {
1148
+ const ch = arg1[i];
1149
+ for (let j = 0; j < mapping.length; j += 1) {
1150
+ if (mapping[j] === i + 1) reordered[j] = ch;
1151
+ }
1152
+ }
1153
+ const source = reordered.join("");
1154
+ let out = "";
1155
+ for (let i = 0; i < source.length && i < xorSeed.length; i += 2) {
1156
+ const left = Number.parseInt(source.slice(i, i + 2), 16);
1157
+ const right = Number.parseInt(xorSeed.slice(i, i + 2), 16);
1158
+ if (Number.isNaN(left) || Number.isNaN(right)) return "";
1159
+ out += (left ^ right).toString(16).padStart(2, "0");
1160
+ }
1161
+ return out;
1162
+ }
1163
+ function upsertCookie(cookieHeader, name, value) {
1164
+ const parts = String(cookieHeader || "").split(";").map((part) => part.trim()).filter(Boolean);
1165
+ let replaced = false;
1166
+ const next = parts.map((part) => {
1167
+ const eq = part.indexOf("=");
1168
+ if (eq < 0) return part;
1169
+ const key = part.slice(0, eq).trim();
1170
+ if (key !== name) return part;
1171
+ replaced = true;
1172
+ return `${name}=${value}`;
1173
+ });
1174
+ if (!replaced) next.push(`${name}=${value}`);
1175
+ return next.join("; ");
1176
+ }
1177
+ function collectSetCookieHeaders(headers) {
1178
+ const getSetCookie = headers?.getSetCookie;
1179
+ if (typeof getSetCookie === "function") return getSetCookie.call(headers) || [];
1180
+ const single = headers?.get?.("set-cookie");
1181
+ return single ? [single] : [];
1182
+ }
1183
+ function mergeSetCookiePairs(cookieHeader, setCookieHeaders) {
1184
+ let merged = cookieHeader || "";
1185
+ for (const raw of setCookieHeaders || []) {
1186
+ const firstPair = String(raw || "").split(";")[0]?.trim();
1187
+ if (!firstPair) continue;
1188
+ const eq = firstPair.indexOf("=");
1189
+ if (eq <= 0) continue;
1190
+ merged = upsertCookie(merged, firstPair.slice(0, eq).trim(), firstPair.slice(eq + 1));
1191
+ }
1192
+ return merged;
1193
+ }
1194
+ async function requestJson(url, key, options = {}) {
1195
+ let cookieHeader = "";
1196
+ for (let attempt = 0; attempt < 2; attempt += 1) {
1197
+ const controller = new AbortController();
1198
+ const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
1199
+ const response = await fetch(url, {
1200
+ headers: {
1201
+ accept: "application/json",
1202
+ authorization: `Bearer ${options.authKey || key}`,
1203
+ "user-agent": SHIELD_USER_AGENT,
1204
+ ...cookieHeader ? { cookie: cookieHeader } : {},
1205
+ ...options.headers || {}
1206
+ },
1207
+ signal: controller.signal
1208
+ });
1209
+ try {
1210
+ const body = await response.text();
1211
+ cookieHeader = mergeSetCookiePairs(cookieHeader, collectSetCookieHeaders(response.headers));
1212
+ let json = {};
1213
+ try {
1214
+ json = body ? JSON.parse(body) : {};
1215
+ } catch {
1216
+ const contentType = response.headers.get("content-type") || "";
1217
+ const acwScV2 = isShieldChallenge(contentType, body) ? solveNewApiAcwScV2(body) : "";
1218
+ await debugLog({
1219
+ source: options.name || "usage",
1220
+ url,
1221
+ status: response.status,
1222
+ contentType,
1223
+ shieldRetry: Boolean(acwScV2 && attempt === 0),
1224
+ bodyPreview: shortPreview(body)
1225
+ });
1226
+ if (acwScV2 && attempt === 0) {
1227
+ cookieHeader = upsertCookie(cookieHeader, "acw_sc__v2", acwScV2);
1228
+ continue;
1229
+ }
1230
+ throw new Error(`${options.name || "usage"} returned non-JSON (${response.status})`);
1231
+ }
1232
+ if (!response.ok) {
1233
+ const message = json?.error?.message || json?.message || response.statusText;
1234
+ await debugLog({
1235
+ source: options.name || "usage",
1236
+ url,
1237
+ status: response.status,
1238
+ message,
1239
+ bodyPreview: shortPreview(body)
1240
+ });
1241
+ throw new Error(`${options.name || "usage"} failed (${response.status} ${message})`);
1242
+ }
1243
+ return json;
1244
+ } finally {
1245
+ clearTimeout(timeout);
1246
+ }
1247
+ }
1248
+ throw new Error(`${options.name || "usage"} unavailable`);
1249
+ }
1250
+
1251
+ // integrations/usage/lib/format.mjs
1252
+ function pickNumber(obj, keys) {
1253
+ for (const key of keys) {
1254
+ const value = obj?.[key];
1255
+ if (typeof value === "number" && Number.isFinite(value)) return value;
1256
+ if (typeof value === "string" && value.trim() && Number.isFinite(Number(value))) return Number(value);
1257
+ }
1258
+ return void 0;
1259
+ }
1260
+ function formatMoney(value) {
1261
+ return `$${value.toFixed(value >= 100 ? 0 : 1)}`;
1262
+ }
1263
+ function formatMaybeMoney(value, unit = "USD") {
1264
+ if (unit === "USD" || unit === "$") return formatMoney(value);
1265
+ return `${value.toLocaleString("en-US", { maximumFractionDigits: 1 })} ${unit}`;
1266
+ }
1267
+ function usageParts() {
1268
+ return ["API"];
1269
+ }
1270
+ async function formatNewApiQuota(value) {
1271
+ const scale = await newApiQuotaScale();
1272
+ if (Number.isFinite(scale) && scale > 0) return formatMoney(value / scale);
1273
+ return value.toLocaleString("en-US", { maximumFractionDigits: 0 });
1274
+ }
1275
+ function usageRoot(data) {
1276
+ return data?.data && typeof data.data === "object" ? data.data : data;
1277
+ }
1278
+ function shortDate(value) {
1279
+ if (!value) return "";
1280
+ const match = String(value).match(/^(\d{4})-(\d{2})-(\d{2})/);
1281
+ return match ? `${match[2]}-${match[3]}` : "";
1282
+ }
1283
+ function hasSubscriptionLimits(root) {
1284
+ const sub = root?.subscription || {};
1285
+ return [
1286
+ "daily_limit_usd",
1287
+ "weekly_limit_usd",
1288
+ "monthly_limit_usd",
1289
+ "daily_usage_usd",
1290
+ "weekly_usage_usd",
1291
+ "monthly_usage_usd"
1292
+ ].some((key) => pickNumber(sub, [key]) !== void 0);
1293
+ }
1294
+ function isQuotaLimitedUsage(root) {
1295
+ return root?.mode === "quota_limited" || root?.quota;
1296
+ }
1297
+ function isSubscriptionUsage(root) {
1298
+ return hasSubscriptionLimits(root) || root?.mode === "unrestricted" && root?.subscription;
1299
+ }
1300
+ function isWalletUsage(root) {
1301
+ const planName = String(root?.planName || "");
1302
+ return root?.mode === "unrestricted" && !isSubscriptionUsage(root) || planName.includes("\u94B1\u5305") || planName.toLowerCase().includes("wallet") || pickNumber(root, ["balance"]) !== void 0 && !hasSubscriptionLimits(root);
1303
+ }
1304
+ function hasV1UsageFields(root) {
1305
+ return hasSubscriptionLimits(root) || pickNumber(root, [
1306
+ "balance",
1307
+ "remaining",
1308
+ "remain",
1309
+ "available",
1310
+ "hard_limit_usd",
1311
+ "hard_limit",
1312
+ "total_granted",
1313
+ "quota",
1314
+ "total_usage",
1315
+ "used",
1316
+ "usage"
1317
+ ]) !== void 0 || pickNumber(root?.quota, ["limit", "quota", "used", "quota_used", "remaining"]) !== void 0 || pickNumber(root?.usage?.today, ["actual_cost", "cost"]) !== void 0 || Array.isArray(root?.daily_usage) && root.daily_usage.length > 0;
1318
+ }
1319
+ async function formatQuota(label, data) {
1320
+ const root = usageRoot(data);
1321
+ const unit = root?.unit || "USD";
1322
+ const remaining = pickNumber(root, ["remaining"]);
1323
+ const hardLimit = pickNumber(root, ["hard_limit_usd", "hard_limit", "total_granted", "quota"]);
1324
+ const used = pickNumber(root, ["total_usage", "used", "usage"]);
1325
+ const balance = pickNumber(root, ["balance", "remaining", "remain", "available"]);
1326
+ if (isQuotaLimitedUsage(root)) return formatQuotaLimitedLine(label, root);
1327
+ if (isSubscriptionUsage(root)) return formatUsageLine(label, root);
1328
+ if (isWalletUsage(root)) return await formatWalletLine(label, root);
1329
+ if (remaining !== void 0) return formatUsageLine(label, root);
1330
+ if (balance !== void 0) return `API | balance ${formatMaybeMoney(balance, unit)}`;
1331
+ if (hardLimit !== void 0 && used !== void 0) {
1332
+ return `API | remaining ${formatMaybeMoney(Math.max(0, hardLimit - used), unit)}`;
1333
+ }
1334
+ if (hardLimit !== void 0) return `API | total ${formatMaybeMoney(hardLimit, unit)}`;
1335
+ const keys = Object.keys(root || {}).slice(0, 4).join(", ");
1336
+ return keys ? `API | received (${keys})` : `API | checked ${unit}`;
1337
+ }
1338
+ async function formatNewApiTokenLine(label, data) {
1339
+ const root = usageRoot(data);
1340
+ const unlimited = root?.unlimited_quota === true || root?.unlimitedQuota === true;
1341
+ const quota = pickNumber(root, ["quota", "limit", "total_quota", "totalQuota"]);
1342
+ const used = pickNumber(root, ["used_quota", "usedQuota", "used"]);
1343
+ let remaining = pickNumber(root, ["remain_quota", "remainQuota", "remaining", "balance"]);
1344
+ if (remaining === void 0 && quota !== void 0 && used !== void 0) {
1345
+ remaining = Math.max(0, quota - used);
1346
+ }
1347
+ if (!unlimited && quota === void 0 && used === void 0 && remaining === void 0) {
1348
+ throw new Error("NewAPI token usage payload has no quota fields");
1349
+ }
1350
+ const parts = usageParts();
1351
+ if (unlimited) parts.push("unlimited");
1352
+ if (remaining !== void 0) parts.push(`balance ${await formatNewApiQuota(remaining)}`);
1353
+ if (used !== void 0 && quota !== void 0) {
1354
+ parts.push(`used ${await formatNewApiQuota(used)}/${await formatNewApiQuota(quota)}`);
1355
+ } else if (used !== void 0) {
1356
+ parts.push(`used ${await formatNewApiQuota(used)}`);
1357
+ }
1358
+ return parts.join(" | ");
1359
+ }
1360
+ function formatOpenRouterLine(label, data) {
1361
+ const root = usageRoot(data);
1362
+ const limit = pickNumber(root, ["limit", "limit_remaining", "total_credits"]);
1363
+ const remaining = pickNumber(root, ["limit_remaining", "remaining_credits"]);
1364
+ const used = pickNumber(root, ["usage", "total_usage", "spend"]);
1365
+ const reset = root?.limit_reset || root?.reset_at ? shortDate(root.limit_reset || root.reset_at) : "";
1366
+ const parts = usageParts();
1367
+ if (remaining !== void 0) parts.push(`balance ${formatMoney(remaining)}`);
1368
+ if (used !== void 0 && limit !== void 0 && limit !== remaining) {
1369
+ parts.push(`used ${formatMoney(used)}/${formatMoney(limit)}`);
1370
+ } else if (used !== void 0) {
1371
+ parts.push(`used ${formatMoney(used)}`);
1372
+ }
1373
+ if (reset) parts.push(`Reset ${reset}`);
1374
+ if (parts.length === 1) throw new Error("OpenRouter payload has no usage fields");
1375
+ return parts.join(" | ");
1376
+ }
1377
+ function panelQuotaScale(kind) {
1378
+ return kind === "veloera" ? 1e6 : DEFAULT_NEW_API_QUOTA_SCALE;
1379
+ }
1380
+ function panelQuotaLooksRemaining(kind) {
1381
+ return ["new-api", "anyrouter", "agentrouter", "done-hub", "donehub"].includes(kind);
1382
+ }
1383
+ async function formatPanelUserSelfLine(label, data, kind) {
1384
+ const root = usageRoot(data);
1385
+ const scale = panelQuotaScale(kind);
1386
+ const quota = pickNumber(root, ["quota"]);
1387
+ const used = pickNumber(root, ["used_quota", "usedQuota"]);
1388
+ const todayIncome = pickNumber(root, ["today_income", "todayIncome"]);
1389
+ const todayUsed = pickNumber(root, ["today_quota_consumption", "todayQuotaConsumption"]);
1390
+ if (quota === void 0 && used === void 0) {
1391
+ throw new Error("panel /api/user/self payload has no quota fields");
1392
+ }
1393
+ const quotaUsd = quota === void 0 ? void 0 : quota / scale;
1394
+ const usedUsd = used === void 0 ? void 0 : used / scale;
1395
+ const remainingUsd = panelQuotaLooksRemaining(kind) ? quotaUsd : quotaUsd === void 0 || usedUsd === void 0 ? quotaUsd : Math.max(0, quotaUsd - usedUsd);
1396
+ const totalUsd = panelQuotaLooksRemaining(kind) ? quotaUsd === void 0 || usedUsd === void 0 ? quotaUsd : quotaUsd + usedUsd : quotaUsd;
1397
+ const parts = usageParts();
1398
+ if (remainingUsd !== void 0) parts.push(`balance ${formatMoney(remainingUsd)}`);
1399
+ if (usedUsd !== void 0 && totalUsd !== void 0) {
1400
+ parts.push(`used ${formatMoney(usedUsd)}/${formatMoney(totalUsd)}`);
1401
+ } else if (usedUsd !== void 0) {
1402
+ parts.push(`used ${formatMoney(usedUsd)}`);
1403
+ }
1404
+ if (todayUsed !== void 0) parts.push(`today ${formatMoney(todayUsed / scale)}`);
1405
+ if (todayIncome !== void 0) parts.push(`income ${formatMoney(todayIncome / scale)}`);
1406
+ return parts.join(" | ");
1407
+ }
1408
+ function formatQuotaLimitedLine(label, root) {
1409
+ const quota = root?.quota || {};
1410
+ const limit = pickNumber(quota, ["limit", "quota"]);
1411
+ const used = pickNumber(quota, ["used", "quota_used"]);
1412
+ const remaining = pickNumber(quota, ["remaining"]) ?? pickNumber(root, ["remaining"]);
1413
+ const parts = usageParts();
1414
+ if (limit !== void 0 && used !== void 0) {
1415
+ parts.push(`Q ${formatMoney(used)}/${formatMoney(limit)}`);
1416
+ } else if (remaining !== void 0) {
1417
+ parts.push(`remaining ${formatMoney(remaining)}`);
1418
+ }
1419
+ if (Array.isArray(root?.rate_limits) && root.rate_limits.length > 0) {
1420
+ const rateParts = root.rate_limits.map((entry) => {
1421
+ const window = entry?.window;
1422
+ const rateLimit = pickNumber(entry, ["limit"]);
1423
+ const rateUsed = pickNumber(entry, ["used"]);
1424
+ return window && rateLimit !== void 0 && rateUsed !== void 0 ? `${window} ${formatMoney(rateUsed)}/${formatMoney(rateLimit)}` : "";
1425
+ }).filter(Boolean);
1426
+ if (rateParts.length > 0) parts.push(rateParts.join(", "));
1427
+ }
1428
+ return parts.join(" | ");
1429
+ }
1430
+ async function formatWalletLine(label, root) {
1431
+ const balance = pickNumber(root, ["balance", "remaining", "remain", "available"]);
1432
+ const todayCost = pickNumber(root?.usage?.today, ["actual_cost", "cost"]);
1433
+ const recentUsage = Array.isArray(root?.daily_usage) ? root.daily_usage.reduce((sum, day) => sum + (pickNumber(day, ["actual_cost", "cost"]) || 0), 0) : void 0;
1434
+ const parts = usageParts();
1435
+ if (balance !== void 0) parts.push(`balance ${formatMoney(balance)}`);
1436
+ if (todayCost !== void 0) parts.push(`today ${formatMoney(todayCost)}`);
1437
+ if (recentUsage !== void 0 && root.daily_usage.length > 0) {
1438
+ parts.push(`${await providerUsageDays()}d ${formatMoney(recentUsage)}`);
1439
+ }
1440
+ return parts.join(" | ");
1441
+ }
1442
+ function formatUsageLine(label, root) {
1443
+ const sub = root?.subscription || {};
1444
+ const dailyLimit = pickNumber(sub, ["daily_limit_usd"]);
1445
+ const dailyUsage = pickNumber(sub, ["daily_usage_usd"]);
1446
+ const weeklyLimit = pickNumber(sub, ["weekly_limit_usd"]);
1447
+ const weeklyUsage = pickNumber(sub, ["weekly_usage_usd"]);
1448
+ const monthlyLimit = pickNumber(sub, ["monthly_limit_usd"]);
1449
+ const monthlyUsage = pickNumber(sub, ["monthly_usage_usd"]);
1450
+ const expires = shortDate(sub.expires_at);
1451
+ const parts = usageParts();
1452
+ if (dailyLimit > 0 && dailyUsage !== void 0) parts.push(`D ${formatMoney(dailyUsage)}/${formatMoney(dailyLimit)}`);
1453
+ if (weeklyLimit > 0 && weeklyUsage !== void 0) parts.push(`W ${formatMoney(weeklyUsage)}/${formatMoney(weeklyLimit)}`);
1454
+ if (monthlyLimit > 0 && monthlyUsage !== void 0) parts.push(`M ${formatMoney(monthlyUsage)}/${formatMoney(monthlyLimit)}`);
1455
+ if (expires) parts.push(`Exp ${expires}`);
1456
+ return parts.join(" | ");
1457
+ }
1458
+
1459
+ // integrations/usage/lib/routes.mjs
1460
+ async function subscriptionUrl(baseUrl) {
1461
+ const clean = baseUrl.replace(/\/+$/, "");
1462
+ const url = clean.endsWith("/v1") ? `${clean}/usage` : `${clean}/v1/usage`;
1463
+ return `${url}?days=${await providerUsageDays()}`;
1464
+ }
1465
+ function usageResult(context, source, text, raw) {
1466
+ return {
1467
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1468
+ baseUrl: context.baseUrl,
1469
+ provider: context.providerName,
1470
+ source,
1471
+ text,
1472
+ raw
1473
+ };
1474
+ }
1475
+ async function fetchV1Usage(context) {
1476
+ const json = await requestJson(await subscriptionUrl(context.baseUrl), context.key, {
1477
+ name: "v1 usage"
1478
+ });
1479
+ if (!hasV1UsageFields(usageRoot(json))) throw new Error("v1 usage payload has no usage fields");
1480
+ return usageResult(context, "v1-usage", await formatQuota(context.label, json), json);
1481
+ }
1482
+ async function fetchNewApiTokenUsage(context) {
1483
+ const json = await requestJson(joinUrl(serviceRoot(context.baseUrl), "/api/usage/token/"), context.key, {
1484
+ name: "NewAPI token usage"
1485
+ });
1486
+ const root = usageRoot(json);
1487
+ const quota = pickNumber(root, ["quota", "limit", "total_quota", "totalQuota"]);
1488
+ const used = pickNumber(root, ["used_quota", "usedQuota", "used"]);
1489
+ let remaining = pickNumber(root, ["remain_quota", "remainQuota", "remaining", "balance"]);
1490
+ if (remaining === void 0 && quota !== void 0 && used !== void 0) {
1491
+ remaining = Math.max(0, quota - used);
1492
+ }
1493
+ const scale = await newApiQuotaScale();
1494
+ const quotaForWarning = scale ? quota / scale : quota;
1495
+ const usedForWarning = scale ? used / scale : used;
1496
+ const remainingForWarning = scale ? remaining / scale : remaining;
1497
+ const normalized = {
1498
+ mode: "quota_limited",
1499
+ quota: {
1500
+ limit: quotaForWarning,
1501
+ used: usedForWarning,
1502
+ remaining: remainingForWarning
1503
+ },
1504
+ unit: scale ? "USD" : "quota",
1505
+ source: "newapi-token",
1506
+ raw: json
1507
+ };
1508
+ return usageResult(context, "newapi-token", await formatNewApiTokenLine(context.label, json), normalized);
1509
+ }
1510
+ async function fetchPanelUserSelfUsage(context) {
1511
+ const preset = await usagePreset();
1512
+ const kind = preset === "auto" ? "new-api" : preset;
1513
+ const json = await requestJson(joinUrl(serviceRoot(context.baseUrl), "/api/user/self"), context.key, {
1514
+ name: "panel /api/user/self",
1515
+ headers: await panelUserHeaders()
1516
+ });
1517
+ const root = usageRoot(json);
1518
+ if (pickNumber(root, ["quota"]) === void 0 && pickNumber(root, ["used_quota", "usedQuota"]) === void 0) {
1519
+ await debugLog({
1520
+ source: "panel /api/user/self",
1521
+ payloadKeys: Object.keys(root || {}).slice(0, 20),
1522
+ success: root?.success,
1523
+ message: root?.message || root?.error?.message || ""
1524
+ });
1525
+ }
1526
+ const scale = panelQuotaScale(kind);
1527
+ const quota = pickNumber(root, ["quota"]);
1528
+ const used = pickNumber(root, ["used_quota", "usedQuota"]);
1529
+ const remaining = panelQuotaLooksRemaining(kind) ? quota : quota === void 0 || used === void 0 ? quota : Math.max(0, quota - used);
1530
+ const total = panelQuotaLooksRemaining(kind) ? quota === void 0 || used === void 0 ? quota : quota + used : quota;
1531
+ const normalized = {
1532
+ mode: "quota_limited",
1533
+ quota: {
1534
+ limit: total === void 0 ? void 0 : total / scale,
1535
+ used: used === void 0 ? void 0 : used / scale,
1536
+ remaining: remaining === void 0 ? void 0 : remaining / scale
1537
+ },
1538
+ unit: "USD",
1539
+ source: "panel-user-self",
1540
+ raw: json
1541
+ };
1542
+ return usageResult(
1543
+ context,
1544
+ "panel-user-self",
1545
+ await formatPanelUserSelfLine(context.label, json, kind),
1546
+ normalized
1547
+ );
1548
+ }
1549
+ async function fetchSub2ApiAuthMeUsage(context) {
1550
+ const json = await requestJson(joinUrl(serviceRoot(context.baseUrl), "/api/v1/auth/me"), context.key, {
1551
+ name: "Sub2API auth/me"
1552
+ });
1553
+ const root = usageRoot(json);
1554
+ const balance = pickNumber(root, ["balance"]);
1555
+ if (balance === void 0) throw new Error("Sub2API auth/me payload has no balance field");
1556
+ const normalized = {
1557
+ mode: "unrestricted",
1558
+ planName: root?.username || root?.email || context.label || "Sub2API",
1559
+ balance,
1560
+ unit: "USD",
1561
+ source: "sub2api-auth-me",
1562
+ raw: json
1563
+ };
1564
+ return usageResult(
1565
+ context,
1566
+ "sub2api-auth-me",
1567
+ `API | balance ${formatMoney(balance)}`,
1568
+ normalized
1569
+ );
1570
+ }
1571
+ async function fetchOpenRouterUsage(context) {
1572
+ const base = cleanBaseUrl(context.baseUrl).includes("/api/v1") ? cleanBaseUrl(context.baseUrl) : joinUrl(serviceRoot(context.baseUrl), "/api/v1");
1573
+ const endpoints = [
1574
+ { source: "openrouter-key", url: joinUrl(base, "/key") },
1575
+ { source: "openrouter-credits", url: joinUrl(base, "/credits") }
1576
+ ];
1577
+ let lastError;
1578
+ for (const endpoint of endpoints) {
1579
+ try {
1580
+ const json = await requestJson(endpoint.url, context.key, { name: endpoint.source });
1581
+ return usageResult(context, endpoint.source, formatOpenRouterLine("OpenRouter", json), json);
1582
+ } catch (error) {
1583
+ lastError = error;
1584
+ await debugLog({ source: endpoint.source, error: error.message });
1585
+ }
1586
+ }
1587
+ throw lastError || new Error("OpenRouter usage unavailable");
1588
+ }
1589
+ var USAGE_ROUTES = {
1590
+ "v1-usage": {
1591
+ id: "v1-usage",
1592
+ path: "/v1/usage",
1593
+ run: fetchV1Usage
1594
+ },
1595
+ "sub2api-auth-me": {
1596
+ id: "sub2api-auth-me",
1597
+ path: "/api/v1/auth/me",
1598
+ run: fetchSub2ApiAuthMeUsage
1599
+ },
1600
+ "newapi-token": {
1601
+ id: "newapi-token",
1602
+ path: "/api/usage/token/",
1603
+ run: fetchNewApiTokenUsage
1604
+ },
1605
+ "panel-user-self": {
1606
+ id: "panel-user-self",
1607
+ path: "/api/user/self",
1608
+ run: fetchPanelUserSelfUsage
1609
+ },
1610
+ "openrouter": {
1611
+ id: "openrouter",
1612
+ path: "/api/v1/key",
1613
+ run: fetchOpenRouterUsage
1614
+ }
1615
+ };
1616
+ async function usageRouteIds(context) {
1617
+ const preset = await usagePreset();
1618
+ const routes = {
1619
+ "sub2api": ["v1-usage", "sub2api-auth-me"],
1620
+ "openai-compatible": ["v1-usage"],
1621
+ "new-api": ["newapi-token", "panel-user-self"],
1622
+ "one-api": ["newapi-token", "panel-user-self"],
1623
+ "onehub": ["newapi-token", "panel-user-self"],
1624
+ "one-hub": ["newapi-token", "panel-user-self"],
1625
+ "donehub": ["newapi-token", "panel-user-self"],
1626
+ "done-hub": ["newapi-token", "panel-user-self"],
1627
+ "veloera": ["panel-user-self", "newapi-token"],
1628
+ "anyrouter": ["newapi-token", "panel-user-self", "v1-usage"],
1629
+ "agentrouter": ["newapi-token", "panel-user-self", "v1-usage"],
1630
+ "openrouter": ["openrouter"]
1631
+ };
1632
+ if (routes[preset]) return routes[preset];
1633
+ if (preset !== "auto") return [];
1634
+ if (hostIncludes(context.baseUrl, "openrouter.ai")) return ["openrouter"];
1635
+ return ["v1-usage", "sub2api-auth-me", "newapi-token", "panel-user-self"];
1636
+ }
1637
+ async function cachedUsageRoute(context) {
1638
+ const cache = await readRouteCache();
1639
+ const key = usageRouteCacheKey(context.baseUrl);
1640
+ const route = cache.routes[key];
1641
+ return route?.route && USAGE_ROUTES[route.route] ? route : null;
1642
+ }
1643
+ async function orderedUsageRoutes(context) {
1644
+ const routeIds = await usageRouteIds(context);
1645
+ const cached = await cachedUsageRoute(context);
1646
+ if (!cached || !routeIds.includes(cached.route)) return routeIds.map((id) => USAGE_ROUTES[id]).filter(Boolean);
1647
+ await debugLog({
1648
+ source: "route-cache",
1649
+ key: usageRouteCacheKey(context.baseUrl),
1650
+ route: cached.route,
1651
+ path: cached.path || USAGE_ROUTES[cached.route]?.path || ""
1652
+ });
1653
+ return [cached.route, ...routeIds.filter((id) => id !== cached.route)].map((id) => USAGE_ROUTES[id]).filter(Boolean);
1654
+ }
1655
+
1656
+ // integrations/usage/lib/context.mjs
1657
+ import { existsSync as existsSync2 } from "node:fs";
1658
+ function stripInlineComment(value) {
1659
+ let inSingle = false;
1660
+ let inDouble = false;
1661
+ for (let i = 0; i < value.length; i += 1) {
1662
+ const char = value[i];
1663
+ const prev = value[i - 1];
1664
+ if (char === "'" && !inDouble) inSingle = !inSingle;
1665
+ if (char === '"' && !inSingle && prev !== "\\") inDouble = !inDouble;
1666
+ if (char === "#" && !inSingle && !inDouble) return value.slice(0, i).trim();
1667
+ }
1668
+ return value.trim();
1669
+ }
1670
+ function parseTomlLite(source) {
1671
+ const root = {};
1672
+ let current = root;
1673
+ for (const rawLine of source.split(/\r?\n/)) {
1674
+ const line = rawLine.trim();
1675
+ if (!line || line.startsWith("#")) continue;
1676
+ const table = line.match(/^\[([^\]]+)\]$/);
1677
+ if (table) {
1678
+ current = root;
1679
+ for (const part of table[1].split(".")) {
1680
+ const key2 = part.replace(/^['"]|['"]$/g, "");
1681
+ current[key2] ||= {};
1682
+ current = current[key2];
1683
+ }
1684
+ continue;
1685
+ }
1686
+ const eq = line.indexOf("=");
1687
+ if (eq === -1) continue;
1688
+ const key = line.slice(0, eq).trim();
1689
+ const rawValue = stripInlineComment(line.slice(eq + 1));
1690
+ current[key] = parseTomlValue(rawValue);
1691
+ }
1692
+ return root;
1693
+ }
1694
+ function parseTomlValue(value) {
1695
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
1696
+ return value.slice(1, -1);
1697
+ }
1698
+ if (value === "true") return true;
1699
+ if (value === "false") return false;
1700
+ return value;
1701
+ }
1702
+ function activeProvider(config) {
1703
+ const providerName = config.model_provider || "openai";
1704
+ const provider = config.model_providers?.[providerName] || {};
1705
+ return { providerName, provider };
1706
+ }
1707
+ function apiKeyFor(auth, provider) {
1708
+ if (process.env.PROVIDER_USAGE_API_KEY) return process.env.PROVIDER_USAGE_API_KEY;
1709
+ if (process.env.SUB2API_API_KEY) return process.env.SUB2API_API_KEY;
1710
+ if (provider.env_key && process.env[provider.env_key]) return process.env[provider.env_key];
1711
+ if (auth.OPENAI_API_KEY) return auth.OPENAI_API_KEY;
1712
+ if (process.env.OPENAI_API_KEY) return process.env.OPENAI_API_KEY;
1713
+ return "";
1714
+ }
1715
+ function apiKeyForClaude() {
1716
+ return process.env.PROVIDER_USAGE_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN || process.env.ANTHROPIC_API_KEY || "";
1717
+ }
1718
+ function providerLabel(providerName, provider) {
1719
+ return String(provider.name || providerName || "API").toUpperCase();
1720
+ }
1721
+ async function contextForCodex() {
1722
+ const auth = existsSync2(AUTH_PATH) ? await readJson(AUTH_PATH) : {};
1723
+ const codexConfig = parseTomlLite(await readTextIfExists(CODEX_CONFIG_PATH));
1724
+ const { providerName, provider } = activeProvider(codexConfig);
1725
+ const baseUrl = process.env.PROVIDER_USAGE_BASE_URL || process.env.SUB2API_BASE_URL || process.env.OPENAI_BASE_URL || provider.base_url || "";
1726
+ const key = apiKeyFor(auth, provider);
1727
+ return {
1728
+ providerName,
1729
+ provider,
1730
+ baseUrl,
1731
+ key,
1732
+ label: providerLabel(providerName, provider)
1733
+ };
1734
+ }
1735
+ function contextForClaude() {
1736
+ const baseUrl = process.env.PROVIDER_USAGE_BASE_URL || process.env.ANTHROPIC_BASE_URL || "";
1737
+ return {
1738
+ providerName: "claude",
1739
+ provider: { name: "Claude" },
1740
+ baseUrl,
1741
+ key: apiKeyForClaude(),
1742
+ label: "Claude"
1743
+ };
1744
+ }
1745
+ async function usageContext(agent) {
1746
+ return agent === "claude" ? contextForClaude() : await contextForCodex();
1747
+ }
1748
+ function normalizeUsageContext(input) {
1749
+ const providerName = String(input?.providerName || "provider");
1750
+ const provider = input?.provider && typeof input.provider === "object" ? input.provider : { name: providerName };
1751
+ return {
1752
+ providerName,
1753
+ provider,
1754
+ baseUrl: String(input?.baseUrl || ""),
1755
+ key: String(input?.key || ""),
1756
+ label: String(input?.label || provider.name || providerName)
1757
+ };
1758
+ }
1759
+
1760
+ // integrations/usage/core.mjs
1761
+ function parseArgs(argv) {
1762
+ const opts = { mode: "hook", agent: "codex" };
1763
+ let modeSet = false;
1764
+ for (let i = 0; i < argv.length; i += 1) {
1765
+ const arg = argv[i];
1766
+ if (arg === "--agent" && argv[i + 1]) {
1767
+ opts.agent = argv[++i];
1768
+ } else if (arg.startsWith("--agent=")) {
1769
+ opts.agent = arg.slice("--agent=".length);
1770
+ } else if (!arg.startsWith("-") && !modeSet) {
1771
+ opts.mode = arg;
1772
+ modeSet = true;
1773
+ }
1774
+ }
1775
+ return opts;
1776
+ }
1777
+ var cli = parseArgs(process.argv.slice(2));
1778
+ var mode = cli.mode;
1779
+ function hookOut(message) {
1780
+ const payload = { continue: true };
1781
+ if (message) payload.systemMessage = message;
1782
+ process.stdout.write(`${JSON.stringify(payload)}
1783
+ `);
1784
+ }
1785
+ function textOut(message) {
1786
+ if (message) process.stdout.write(`${message}
1787
+ `);
1788
+ }
1789
+ function failSoft(message, error) {
1790
+ const detail = error?.message ? `: ${error.message}` : "";
1791
+ if (mode === "hook") hookOut();
1792
+ else if (mode !== "refresh") textOut(`${message}${detail}`);
1793
+ }
1794
+ async function queryUsageContext(context, { agent = "external", rememberSnapshot = false } = {}) {
1795
+ await debugLog({
1796
+ mode,
1797
+ agent,
1798
+ providerName: context.providerName,
1799
+ baseUrl: context.baseUrl,
1800
+ preset: await usagePreset(),
1801
+ providerEnvKey: context.provider?.env_key || "",
1802
+ hasProviderUsageKey: Boolean(process.env.PROVIDER_USAGE_API_KEY),
1803
+ hasSub2apiKey: Boolean(process.env.SUB2API_API_KEY),
1804
+ hasProviderEnvKey: Boolean(context.provider?.env_key && process.env[context.provider.env_key]),
1805
+ hasAnthropicAuthToken: Boolean(process.env.ANTHROPIC_AUTH_TOKEN),
1806
+ hasAnthropicApiKey: Boolean(process.env.ANTHROPIC_API_KEY),
1807
+ hasEnvOpenaiKey: Boolean(process.env.OPENAI_API_KEY)
1808
+ });
1809
+ if (!context.key || isOfficialBaseUrl(context.baseUrl)) {
1810
+ return { skipped: true, text: "" };
1811
+ }
1812
+ let lastError;
1813
+ for (const route of await orderedUsageRoutes(context)) {
1814
+ try {
1815
+ const result = await route.run(context);
1816
+ await rememberUsageRoute(context, route, result);
1817
+ if (rememberSnapshot) {
1818
+ await rememberUsageSnapshot(context, result);
1819
+ await rememberRefreshState(context, {
1820
+ lastSuccessAt: (/* @__PURE__ */ new Date()).toISOString(),
1821
+ lastError: ""
1822
+ });
1823
+ }
1824
+ return result;
1825
+ } catch (error) {
1826
+ lastError = error;
1827
+ await debugLog({ route: route.id, path: route.path, error: error.message });
1828
+ }
1829
+ }
1830
+ if (lastError) {
1831
+ if (rememberSnapshot) {
1832
+ await rememberRefreshState(context, {
1833
+ lastFailureAt: (/* @__PURE__ */ new Date()).toISOString(),
1834
+ lastError: lastError.message
1835
+ });
1836
+ }
1837
+ throw lastError;
1838
+ }
1839
+ return { skipped: true, text: "" };
1840
+ }
1841
+ async function queryProviderUsage(input, options = {}) {
1842
+ return await queryUsageContext(normalizeUsageContext(input), options);
1843
+ }
1844
+ async function refresh(agent = "codex") {
1845
+ return await queryAgentProviderUsage(agent);
1846
+ }
1847
+ async function queryAgentProviderUsage(agent = "codex") {
1848
+ return await queryUsageContext(await usageContext(agent), {
1849
+ agent,
1850
+ rememberSnapshot: agent === "claude"
1851
+ });
1852
+ }
1853
+ async function main() {
1854
+ try {
1855
+ if (mode === "refresh") {
1856
+ await refresh(cli.agent);
1857
+ } else if (mode === "print" || mode === "print-or-refresh") {
1858
+ const result = await refresh(cli.agent);
1859
+ textOut(result?.text || "");
1860
+ } else if (mode === "hook") {
1861
+ const result = await refresh(cli.agent);
1862
+ hookOut(result?.text || "");
1863
+ } else {
1864
+ throw new Error(`unknown mode: ${mode}`);
1865
+ }
1866
+ } catch (error) {
1867
+ failSoft("Provider usage unavailable", error);
1868
+ }
1869
+ }
1870
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
1871
+ await main();
1872
+ }
1873
+ export {
1874
+ queryAgentProviderUsage,
1875
+ queryProviderUsage
1876
+ };