@cybedefend/vibedefend 1.3.1 → 1.4.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.
- package/README.md +32 -5
- package/bin/resolve.js +19 -0
- package/bin/vibedefend.js +4 -1
- package/dist/api/projects.js +158 -0
- package/dist/api/projects.js.map +1 -0
- package/dist/clients/claude-code.js +2 -2
- package/dist/clients/claude-code.js.map +1 -1
- package/dist/clients/codex.js +2 -2
- package/dist/clients/codex.js.map +1 -1
- package/dist/clients/cursor.js +2 -2
- package/dist/clients/cursor.js.map +1 -1
- package/dist/clients/vscode.js +2 -2
- package/dist/clients/vscode.js.map +1 -1
- package/dist/clients/windsurf.js +2 -2
- package/dist/clients/windsurf.js.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/custom-regions.js +5 -0
- package/dist/custom-regions.js.map +1 -1
- package/dist/endpoints.js +59 -0
- package/dist/endpoints.js.map +1 -0
- package/dist/git.js +103 -0
- package/dist/git.js.map +1 -0
- package/dist/hook-runner.js +554 -281
- package/dist/hooks/install.js +49 -6
- package/dist/hooks/install.js.map +1 -1
- package/dist/hooks/runtime/fetch-rules.js +5 -3
- package/dist/hooks/runtime/fetch-rules.js.map +1 -1
- package/dist/hooks/runtime/judge-injection.js +65 -0
- package/dist/hooks/runtime/judge-injection.js.map +1 -0
- package/dist/hooks/runtime/near-miss.js +6 -1
- package/dist/hooks/runtime/near-miss.js.map +1 -1
- package/dist/hooks/runtime/repo-link-cache.js +116 -0
- package/dist/hooks/runtime/repo-link-cache.js.map +1 -0
- package/dist/hooks/runtime/resolve.js +79 -0
- package/dist/hooks/runtime/resolve.js.map +1 -1
- package/dist/hooks/runtime/session-review.js +10 -3
- package/dist/hooks/runtime/session-review.js.map +1 -1
- package/dist/hooks/runtime/session-start.js +5 -3
- package/dist/hooks/runtime/session-start.js.map +1 -1
- package/dist/hooks/runtime/user-prompt-submit.js +10 -7
- package/dist/hooks/runtime/user-prompt-submit.js.map +1 -1
- package/dist/index.js +40 -2
- package/dist/index.js.map +1 -1
- package/dist/install.js +142 -88
- package/dist/install.js.map +1 -1
- package/dist/link.js +325 -0
- package/dist/link.js.map +1 -0
- package/dist/login.js +2 -23
- package/dist/login.js.map +1 -1
- package/dist/logout.js +87 -0
- package/dist/logout.js.map +1 -0
- package/dist/org-gate.js +110 -0
- package/dist/org-gate.js.map +1 -0
- package/dist/prompts.js +5 -7
- package/dist/prompts.js.map +1 -1
- package/package.json +1 -1
package/dist/hook-runner.js
CHANGED
|
@@ -269,16 +269,16 @@ var require_re2 = __commonJS({
|
|
|
269
269
|
if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
|
|
270
270
|
return UTF8Decoder.decode(heap.subarray(idx, endPtr));
|
|
271
271
|
} else {
|
|
272
|
-
var
|
|
272
|
+
var str2 = "";
|
|
273
273
|
while (idx < endPtr) {
|
|
274
274
|
var u0 = heap[idx++];
|
|
275
275
|
if (!(u0 & 128)) {
|
|
276
|
-
|
|
276
|
+
str2 += String.fromCharCode(u0);
|
|
277
277
|
continue;
|
|
278
278
|
}
|
|
279
279
|
var u1 = heap[idx++] & 63;
|
|
280
280
|
if ((u0 & 224) == 192) {
|
|
281
|
-
|
|
281
|
+
str2 += String.fromCharCode((u0 & 31) << 6 | u1);
|
|
282
282
|
continue;
|
|
283
283
|
}
|
|
284
284
|
var u2 = heap[idx++] & 63;
|
|
@@ -289,27 +289,27 @@ var require_re2 = __commonJS({
|
|
|
289
289
|
u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63;
|
|
290
290
|
}
|
|
291
291
|
if (u0 < 65536) {
|
|
292
|
-
|
|
292
|
+
str2 += String.fromCharCode(u0);
|
|
293
293
|
} else {
|
|
294
294
|
var ch = u0 - 65536;
|
|
295
|
-
|
|
295
|
+
str2 += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
|
-
return
|
|
299
|
+
return str2;
|
|
300
300
|
}
|
|
301
301
|
function UTF8ToString(ptr, maxBytesToRead) {
|
|
302
302
|
return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
|
|
303
303
|
}
|
|
304
|
-
function stringToUTF8Array(
|
|
304
|
+
function stringToUTF8Array(str2, heap, outIdx, maxBytesToWrite) {
|
|
305
305
|
if (!(maxBytesToWrite > 0))
|
|
306
306
|
return 0;
|
|
307
307
|
var startIdx = outIdx;
|
|
308
308
|
var endIdx = outIdx + maxBytesToWrite - 1;
|
|
309
|
-
for (var i = 0; i <
|
|
310
|
-
var u =
|
|
309
|
+
for (var i = 0; i < str2.length; ++i) {
|
|
310
|
+
var u = str2.charCodeAt(i);
|
|
311
311
|
if (u >= 55296 && u <= 57343) {
|
|
312
|
-
var u1 =
|
|
312
|
+
var u1 = str2.charCodeAt(++i);
|
|
313
313
|
u = 65536 + ((u & 1023) << 10) | u1 & 1023;
|
|
314
314
|
}
|
|
315
315
|
if (u <= 127) {
|
|
@@ -336,15 +336,15 @@ var require_re2 = __commonJS({
|
|
|
336
336
|
heap[outIdx] = 0;
|
|
337
337
|
return outIdx - startIdx;
|
|
338
338
|
}
|
|
339
|
-
function stringToUTF8(
|
|
339
|
+
function stringToUTF8(str2, outPtr, maxBytesToWrite) {
|
|
340
340
|
assert(typeof maxBytesToWrite == "number", "stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");
|
|
341
|
-
return stringToUTF8Array(
|
|
341
|
+
return stringToUTF8Array(str2, HEAPU8, outPtr, maxBytesToWrite);
|
|
342
342
|
}
|
|
343
|
-
function lengthBytesUTF8(
|
|
343
|
+
function lengthBytesUTF8(str2) {
|
|
344
344
|
var len = 0;
|
|
345
|
-
for (var i = 0; i <
|
|
346
|
-
var u =
|
|
347
|
-
if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) |
|
|
345
|
+
for (var i = 0; i < str2.length; ++i) {
|
|
346
|
+
var u = str2.charCodeAt(i);
|
|
347
|
+
if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str2.charCodeAt(++i) & 1023;
|
|
348
348
|
if (u <= 127) ++len;
|
|
349
349
|
else if (u <= 2047) len += 2;
|
|
350
350
|
else if (u <= 65535) len += 3;
|
|
@@ -363,16 +363,16 @@ var require_re2 = __commonJS({
|
|
|
363
363
|
if (endPtr - ptr > 32 && UTF16Decoder) {
|
|
364
364
|
return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr));
|
|
365
365
|
} else {
|
|
366
|
-
var
|
|
366
|
+
var str2 = "";
|
|
367
367
|
for (var i = 0; !(i >= maxBytesToRead / 2); ++i) {
|
|
368
368
|
var codeUnit = HEAP16[ptr + i * 2 >> 1];
|
|
369
369
|
if (codeUnit == 0) break;
|
|
370
|
-
|
|
370
|
+
str2 += String.fromCharCode(codeUnit);
|
|
371
371
|
}
|
|
372
|
-
return
|
|
372
|
+
return str2;
|
|
373
373
|
}
|
|
374
374
|
}
|
|
375
|
-
function stringToUTF16(
|
|
375
|
+
function stringToUTF16(str2, outPtr, maxBytesToWrite) {
|
|
376
376
|
assert(outPtr % 2 == 0, "Pointer passed to stringToUTF16 must be aligned to two bytes!");
|
|
377
377
|
assert(typeof maxBytesToWrite == "number", "stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");
|
|
378
378
|
if (maxBytesToWrite === void 0) {
|
|
@@ -381,36 +381,36 @@ var require_re2 = __commonJS({
|
|
|
381
381
|
if (maxBytesToWrite < 2) return 0;
|
|
382
382
|
maxBytesToWrite -= 2;
|
|
383
383
|
var startPtr = outPtr;
|
|
384
|
-
var numCharsToWrite = maxBytesToWrite <
|
|
384
|
+
var numCharsToWrite = maxBytesToWrite < str2.length * 2 ? maxBytesToWrite / 2 : str2.length;
|
|
385
385
|
for (var i = 0; i < numCharsToWrite; ++i) {
|
|
386
|
-
var codeUnit =
|
|
386
|
+
var codeUnit = str2.charCodeAt(i);
|
|
387
387
|
HEAP16[outPtr >> 1] = codeUnit;
|
|
388
388
|
outPtr += 2;
|
|
389
389
|
}
|
|
390
390
|
HEAP16[outPtr >> 1] = 0;
|
|
391
391
|
return outPtr - startPtr;
|
|
392
392
|
}
|
|
393
|
-
function lengthBytesUTF16(
|
|
394
|
-
return
|
|
393
|
+
function lengthBytesUTF16(str2) {
|
|
394
|
+
return str2.length * 2;
|
|
395
395
|
}
|
|
396
396
|
function UTF32ToString(ptr, maxBytesToRead) {
|
|
397
397
|
assert(ptr % 4 == 0, "Pointer passed to UTF32ToString must be aligned to four bytes!");
|
|
398
398
|
var i = 0;
|
|
399
|
-
var
|
|
399
|
+
var str2 = "";
|
|
400
400
|
while (!(i >= maxBytesToRead / 4)) {
|
|
401
401
|
var utf32 = HEAP32[ptr + i * 4 >> 2];
|
|
402
402
|
if (utf32 == 0) break;
|
|
403
403
|
++i;
|
|
404
404
|
if (utf32 >= 65536) {
|
|
405
405
|
var ch = utf32 - 65536;
|
|
406
|
-
|
|
406
|
+
str2 += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
|
|
407
407
|
} else {
|
|
408
|
-
|
|
408
|
+
str2 += String.fromCharCode(utf32);
|
|
409
409
|
}
|
|
410
410
|
}
|
|
411
|
-
return
|
|
411
|
+
return str2;
|
|
412
412
|
}
|
|
413
|
-
function stringToUTF32(
|
|
413
|
+
function stringToUTF32(str2, outPtr, maxBytesToWrite) {
|
|
414
414
|
assert(outPtr % 4 == 0, "Pointer passed to stringToUTF32 must be aligned to four bytes!");
|
|
415
415
|
assert(typeof maxBytesToWrite == "number", "stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");
|
|
416
416
|
if (maxBytesToWrite === void 0) {
|
|
@@ -419,10 +419,10 @@ var require_re2 = __commonJS({
|
|
|
419
419
|
if (maxBytesToWrite < 4) return 0;
|
|
420
420
|
var startPtr = outPtr;
|
|
421
421
|
var endPtr = startPtr + maxBytesToWrite - 4;
|
|
422
|
-
for (var i = 0; i <
|
|
423
|
-
var codeUnit =
|
|
422
|
+
for (var i = 0; i < str2.length; ++i) {
|
|
423
|
+
var codeUnit = str2.charCodeAt(i);
|
|
424
424
|
if (codeUnit >= 55296 && codeUnit <= 57343) {
|
|
425
|
-
var trailSurrogate =
|
|
425
|
+
var trailSurrogate = str2.charCodeAt(++i);
|
|
426
426
|
codeUnit = 65536 + ((codeUnit & 1023) << 10) | trailSurrogate & 1023;
|
|
427
427
|
}
|
|
428
428
|
HEAP32[outPtr >> 2] = codeUnit;
|
|
@@ -432,10 +432,10 @@ var require_re2 = __commonJS({
|
|
|
432
432
|
HEAP32[outPtr >> 2] = 0;
|
|
433
433
|
return outPtr - startPtr;
|
|
434
434
|
}
|
|
435
|
-
function lengthBytesUTF32(
|
|
435
|
+
function lengthBytesUTF32(str2) {
|
|
436
436
|
var len = 0;
|
|
437
|
-
for (var i = 0; i <
|
|
438
|
-
var codeUnit =
|
|
437
|
+
for (var i = 0; i < str2.length; ++i) {
|
|
438
|
+
var codeUnit = str2.charCodeAt(i);
|
|
439
439
|
if (codeUnit >= 55296 && codeUnit <= 57343) ++i;
|
|
440
440
|
len += 4;
|
|
441
441
|
}
|
|
@@ -445,10 +445,10 @@ var require_re2 = __commonJS({
|
|
|
445
445
|
assert(array.length >= 0, "writeArrayToMemory array must have a length (should be an array or typed array)");
|
|
446
446
|
HEAP8.set(array, buffer2);
|
|
447
447
|
}
|
|
448
|
-
function writeAsciiToMemory(
|
|
449
|
-
for (var i = 0; i <
|
|
450
|
-
assert(
|
|
451
|
-
HEAP8[buffer2++ >> 0] =
|
|
448
|
+
function writeAsciiToMemory(str2, buffer2, dontAddNull) {
|
|
449
|
+
for (var i = 0; i < str2.length; ++i) {
|
|
450
|
+
assert(str2.charCodeAt(i) === str2.charCodeAt(i) & 255);
|
|
451
|
+
HEAP8[buffer2++ >> 0] = str2.charCodeAt(i);
|
|
452
452
|
}
|
|
453
453
|
if (!dontAddNull) HEAP8[buffer2 >> 0] = 0;
|
|
454
454
|
}
|
|
@@ -677,8 +677,8 @@ var require_re2 = __commonJS({
|
|
|
677
677
|
};
|
|
678
678
|
Module["FS_createDataFile"] = FS.createDataFile;
|
|
679
679
|
Module["FS_createPreloadedFile"] = FS.createPreloadedFile;
|
|
680
|
-
function hasPrefix(
|
|
681
|
-
return String.prototype.startsWith ?
|
|
680
|
+
function hasPrefix(str2, prefix) {
|
|
681
|
+
return String.prototype.startsWith ? str2.startsWith(prefix) : str2.indexOf(prefix) === 0;
|
|
682
682
|
}
|
|
683
683
|
var dataURIPrefix = "data:application/octet-stream;base64,";
|
|
684
684
|
function isDataURI(filename) {
|
|
@@ -770,9 +770,9 @@ var require_re2 = __commonJS({
|
|
|
770
770
|
module2 = new WebAssembly.Module(binary);
|
|
771
771
|
instance = new WebAssembly.Instance(module2, info);
|
|
772
772
|
} catch (e) {
|
|
773
|
-
var
|
|
774
|
-
err("failed to compile wasm module: " +
|
|
775
|
-
if (
|
|
773
|
+
var str2 = e.toString();
|
|
774
|
+
err("failed to compile wasm module: " + str2);
|
|
775
|
+
if (str2.indexOf("imported Memory") >= 0 || str2.indexOf("memory import") >= 0) {
|
|
776
776
|
err("Memory size incompatibility issues may be due to changing INITIAL_MEMORY at runtime to something too large. Use ALLOW_MEMORY_GROWTH to allow any size memory (and also make sure not to set INITIAL_MEMORY at runtime to something smaller than it was at compile time).");
|
|
777
777
|
}
|
|
778
778
|
throw e;
|
|
@@ -2132,7 +2132,7 @@ var require_re2 = __commonJS({
|
|
|
2132
2132
|
name,
|
|
2133
2133
|
"fromWireType": function(value) {
|
|
2134
2134
|
var length = HEAPU32[value >> 2];
|
|
2135
|
-
var
|
|
2135
|
+
var str2;
|
|
2136
2136
|
if (stdStringIsUTF8) {
|
|
2137
2137
|
var decodeStartPtr = value + 4;
|
|
2138
2138
|
for (var i = 0; i <= length; ++i) {
|
|
@@ -2140,11 +2140,11 @@ var require_re2 = __commonJS({
|
|
|
2140
2140
|
if (i == length || HEAPU8[currentBytePtr] == 0) {
|
|
2141
2141
|
var maxRead = currentBytePtr - decodeStartPtr;
|
|
2142
2142
|
var stringSegment = UTF8ToString(decodeStartPtr, maxRead);
|
|
2143
|
-
if (
|
|
2144
|
-
|
|
2143
|
+
if (str2 === void 0) {
|
|
2144
|
+
str2 = stringSegment;
|
|
2145
2145
|
} else {
|
|
2146
|
-
|
|
2147
|
-
|
|
2146
|
+
str2 += String.fromCharCode(0);
|
|
2147
|
+
str2 += stringSegment;
|
|
2148
2148
|
}
|
|
2149
2149
|
decodeStartPtr = currentBytePtr + 1;
|
|
2150
2150
|
}
|
|
@@ -2154,10 +2154,10 @@ var require_re2 = __commonJS({
|
|
|
2154
2154
|
for (var i = 0; i < length; ++i) {
|
|
2155
2155
|
a[i] = String.fromCharCode(HEAPU8[value + 4 + i]);
|
|
2156
2156
|
}
|
|
2157
|
-
|
|
2157
|
+
str2 = a.join("");
|
|
2158
2158
|
}
|
|
2159
2159
|
_free(value);
|
|
2160
|
-
return
|
|
2160
|
+
return str2;
|
|
2161
2161
|
},
|
|
2162
2162
|
"toWireType": function(destructors, value) {
|
|
2163
2163
|
if (value instanceof ArrayBuffer) {
|
|
@@ -2235,24 +2235,24 @@ var require_re2 = __commonJS({
|
|
|
2235
2235
|
"fromWireType": function(value) {
|
|
2236
2236
|
var length = HEAPU32[value >> 2];
|
|
2237
2237
|
var HEAP2 = getHeap();
|
|
2238
|
-
var
|
|
2238
|
+
var str2;
|
|
2239
2239
|
var decodeStartPtr = value + 4;
|
|
2240
2240
|
for (var i = 0; i <= length; ++i) {
|
|
2241
2241
|
var currentBytePtr = value + 4 + i * charSize;
|
|
2242
2242
|
if (i == length || HEAP2[currentBytePtr >> shift] == 0) {
|
|
2243
2243
|
var maxReadBytes = currentBytePtr - decodeStartPtr;
|
|
2244
2244
|
var stringSegment = decodeString(decodeStartPtr, maxReadBytes);
|
|
2245
|
-
if (
|
|
2246
|
-
|
|
2245
|
+
if (str2 === void 0) {
|
|
2246
|
+
str2 = stringSegment;
|
|
2247
2247
|
} else {
|
|
2248
|
-
|
|
2249
|
-
|
|
2248
|
+
str2 += String.fromCharCode(0);
|
|
2249
|
+
str2 += stringSegment;
|
|
2250
2250
|
}
|
|
2251
2251
|
decodeStartPtr = currentBytePtr + charSize;
|
|
2252
2252
|
}
|
|
2253
2253
|
}
|
|
2254
2254
|
_free(value);
|
|
2255
|
-
return
|
|
2255
|
+
return str2;
|
|
2256
2256
|
},
|
|
2257
2257
|
"toWireType": function(destructors, value) {
|
|
2258
2258
|
if (!(typeof value === "string")) {
|
|
@@ -2592,11 +2592,11 @@ var require_re2 = __commonJS({
|
|
|
2592
2592
|
var WEEKDAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
2593
2593
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
2594
2594
|
function leadingSomething(value, digits, character) {
|
|
2595
|
-
var
|
|
2596
|
-
while (
|
|
2597
|
-
|
|
2595
|
+
var str2 = typeof value === "number" ? value.toString() : value || "";
|
|
2596
|
+
while (str2.length < digits) {
|
|
2597
|
+
str2 = character[0] + str2;
|
|
2598
2598
|
}
|
|
2599
|
-
return
|
|
2599
|
+
return str2;
|
|
2600
2600
|
}
|
|
2601
2601
|
function leadingNulls(value, digits) {
|
|
2602
2602
|
return leadingSomething(value, digits, "0");
|
|
@@ -4502,7 +4502,7 @@ function extractToolInputShape(input, client) {
|
|
|
4502
4502
|
|
|
4503
4503
|
// src/hooks/runtime/resolve.ts
|
|
4504
4504
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
4505
|
-
import { existsSync as
|
|
4505
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "node:fs";
|
|
4506
4506
|
|
|
4507
4507
|
// src/auth/auth-store.ts
|
|
4508
4508
|
import { execFileSync } from "node:child_process";
|
|
@@ -4742,6 +4742,325 @@ async function doRefresh(mcpName, stored) {
|
|
|
4742
4742
|
}
|
|
4743
4743
|
}
|
|
4744
4744
|
|
|
4745
|
+
// src/git.ts
|
|
4746
|
+
import { spawnSync } from "node:child_process";
|
|
4747
|
+
function parseRemoteUrl(url) {
|
|
4748
|
+
const trimmed = url.trim();
|
|
4749
|
+
if (trimmed.length === 0) return null;
|
|
4750
|
+
let host;
|
|
4751
|
+
let rawPath;
|
|
4752
|
+
if (trimmed.includes("://")) {
|
|
4753
|
+
let parsed;
|
|
4754
|
+
try {
|
|
4755
|
+
parsed = new URL(trimmed);
|
|
4756
|
+
} catch {
|
|
4757
|
+
return null;
|
|
4758
|
+
}
|
|
4759
|
+
if (!parsed.hostname) return null;
|
|
4760
|
+
host = parsed.hostname;
|
|
4761
|
+
rawPath = parsed.pathname;
|
|
4762
|
+
} else {
|
|
4763
|
+
const scpMatch = /^(?:[^@\s]+@)?([^:\s/]+):(.+)$/.exec(trimmed);
|
|
4764
|
+
if (!scpMatch) return null;
|
|
4765
|
+
host = scpMatch[1].toLowerCase();
|
|
4766
|
+
rawPath = scpMatch[2];
|
|
4767
|
+
}
|
|
4768
|
+
const slug = rawPath.replace(/^\/+/, "").replace(/\/+$/, "").replace(/\.git$/i, "");
|
|
4769
|
+
if (slug.length === 0) return null;
|
|
4770
|
+
return { provider: detectProvider(host), host, slug };
|
|
4771
|
+
}
|
|
4772
|
+
function detectProvider(host) {
|
|
4773
|
+
const lower = host.toLowerCase();
|
|
4774
|
+
if (lower.includes("github")) return "github";
|
|
4775
|
+
if (lower.includes("gitlab")) return "gitlab";
|
|
4776
|
+
return null;
|
|
4777
|
+
}
|
|
4778
|
+
var GIT_REMOTE_TIMEOUT_MS = 3e3;
|
|
4779
|
+
function getOriginRemote(cwd, deps = {}) {
|
|
4780
|
+
const execImpl = deps.execImpl ?? defaultExecImpl;
|
|
4781
|
+
const result = execImpl("git", ["remote", "get-url", "origin"], {
|
|
4782
|
+
cwd,
|
|
4783
|
+
timeoutMs: GIT_REMOTE_TIMEOUT_MS
|
|
4784
|
+
});
|
|
4785
|
+
if (result.status !== 0) return null;
|
|
4786
|
+
const url = result.stdout.trim();
|
|
4787
|
+
return url.length > 0 ? url : null;
|
|
4788
|
+
}
|
|
4789
|
+
function defaultExecImpl(cmd, args, opts) {
|
|
4790
|
+
const result = spawnSync(cmd, args, {
|
|
4791
|
+
cwd: opts.cwd,
|
|
4792
|
+
encoding: "utf8",
|
|
4793
|
+
timeout: opts.timeoutMs,
|
|
4794
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
4795
|
+
windowsHide: true
|
|
4796
|
+
});
|
|
4797
|
+
return { status: result.status, stdout: result.stdout ?? "" };
|
|
4798
|
+
}
|
|
4799
|
+
|
|
4800
|
+
// src/api/projects.ts
|
|
4801
|
+
var RESOLVE_TIMEOUT_MS = 4e3;
|
|
4802
|
+
function unwrap(body) {
|
|
4803
|
+
if (!body || typeof body !== "object") return {};
|
|
4804
|
+
const root = body;
|
|
4805
|
+
const data = root.data;
|
|
4806
|
+
return data ?? root;
|
|
4807
|
+
}
|
|
4808
|
+
function str(v) {
|
|
4809
|
+
return typeof v === "string" ? v : v == null ? "" : String(v);
|
|
4810
|
+
}
|
|
4811
|
+
async function resolveProjectByRepository(apiBase, token, q, deps = {}) {
|
|
4812
|
+
const f = deps.fetchImpl ?? globalThis.fetch;
|
|
4813
|
+
const params = new URLSearchParams({ provider: q.provider, slug: q.slug });
|
|
4814
|
+
if (q.host) params.set("host", q.host);
|
|
4815
|
+
const url = `${apiBase}/user/projects/resolve?${params.toString()}`;
|
|
4816
|
+
let res;
|
|
4817
|
+
try {
|
|
4818
|
+
res = await f(url, {
|
|
4819
|
+
method: "GET",
|
|
4820
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
4821
|
+
signal: AbortSignal.timeout(deps.timeoutMs ?? RESOLVE_TIMEOUT_MS)
|
|
4822
|
+
});
|
|
4823
|
+
} catch {
|
|
4824
|
+
return null;
|
|
4825
|
+
}
|
|
4826
|
+
if (!res.ok) return null;
|
|
4827
|
+
let body;
|
|
4828
|
+
try {
|
|
4829
|
+
body = await res.json();
|
|
4830
|
+
} catch {
|
|
4831
|
+
return null;
|
|
4832
|
+
}
|
|
4833
|
+
const data = unwrap(body);
|
|
4834
|
+
const rawMatches = Array.isArray(data.matches) ? data.matches : [];
|
|
4835
|
+
return rawMatches.map((raw) => {
|
|
4836
|
+
const m = raw ?? {};
|
|
4837
|
+
return {
|
|
4838
|
+
projectId: str(m.projectId),
|
|
4839
|
+
organizationId: str(m.organizationId),
|
|
4840
|
+
projectName: str(m.projectName),
|
|
4841
|
+
provider: str(m.provider),
|
|
4842
|
+
repository: str(m.repository),
|
|
4843
|
+
// Missing → enabled (default-on). Only an explicit `false` disables.
|
|
4844
|
+
vibedefendEnabled: m.vibedefendEnabled !== false
|
|
4845
|
+
};
|
|
4846
|
+
});
|
|
4847
|
+
}
|
|
4848
|
+
|
|
4849
|
+
// src/hooks/runtime/repo-link-cache.ts
|
|
4850
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
4851
|
+
import { dirname as dirname2 } from "node:path";
|
|
4852
|
+
|
|
4853
|
+
// src/utils.ts
|
|
4854
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
4855
|
+
import { dirname, join as join2 } from "node:path";
|
|
4856
|
+
import { homedir as homedir2, platform } from "node:os";
|
|
4857
|
+
|
|
4858
|
+
// node_modules/.pnpm/kleur@4.1.5/node_modules/kleur/index.mjs
|
|
4859
|
+
var FORCE_COLOR;
|
|
4860
|
+
var NODE_DISABLE_COLORS;
|
|
4861
|
+
var NO_COLOR;
|
|
4862
|
+
var TERM;
|
|
4863
|
+
var isTTY = true;
|
|
4864
|
+
if (typeof process !== "undefined") {
|
|
4865
|
+
({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
|
|
4866
|
+
isTTY = process.stdout && process.stdout.isTTY;
|
|
4867
|
+
}
|
|
4868
|
+
var $ = {
|
|
4869
|
+
enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY),
|
|
4870
|
+
// modifiers
|
|
4871
|
+
reset: init(0, 0),
|
|
4872
|
+
bold: init(1, 22),
|
|
4873
|
+
dim: init(2, 22),
|
|
4874
|
+
italic: init(3, 23),
|
|
4875
|
+
underline: init(4, 24),
|
|
4876
|
+
inverse: init(7, 27),
|
|
4877
|
+
hidden: init(8, 28),
|
|
4878
|
+
strikethrough: init(9, 29),
|
|
4879
|
+
// colors
|
|
4880
|
+
black: init(30, 39),
|
|
4881
|
+
red: init(31, 39),
|
|
4882
|
+
green: init(32, 39),
|
|
4883
|
+
yellow: init(33, 39),
|
|
4884
|
+
blue: init(34, 39),
|
|
4885
|
+
magenta: init(35, 39),
|
|
4886
|
+
cyan: init(36, 39),
|
|
4887
|
+
white: init(37, 39),
|
|
4888
|
+
gray: init(90, 39),
|
|
4889
|
+
grey: init(90, 39),
|
|
4890
|
+
// background colors
|
|
4891
|
+
bgBlack: init(40, 49),
|
|
4892
|
+
bgRed: init(41, 49),
|
|
4893
|
+
bgGreen: init(42, 49),
|
|
4894
|
+
bgYellow: init(43, 49),
|
|
4895
|
+
bgBlue: init(44, 49),
|
|
4896
|
+
bgMagenta: init(45, 49),
|
|
4897
|
+
bgCyan: init(46, 49),
|
|
4898
|
+
bgWhite: init(47, 49)
|
|
4899
|
+
};
|
|
4900
|
+
function run(arr, str2) {
|
|
4901
|
+
let i = 0, tmp, beg = "", end = "";
|
|
4902
|
+
for (; i < arr.length; i++) {
|
|
4903
|
+
tmp = arr[i];
|
|
4904
|
+
beg += tmp.open;
|
|
4905
|
+
end += tmp.close;
|
|
4906
|
+
if (!!~str2.indexOf(tmp.close)) {
|
|
4907
|
+
str2 = str2.replace(tmp.rgx, tmp.close + tmp.open);
|
|
4908
|
+
}
|
|
4909
|
+
}
|
|
4910
|
+
return beg + str2 + end;
|
|
4911
|
+
}
|
|
4912
|
+
function chain(has, keys) {
|
|
4913
|
+
let ctx = { has, keys };
|
|
4914
|
+
ctx.reset = $.reset.bind(ctx);
|
|
4915
|
+
ctx.bold = $.bold.bind(ctx);
|
|
4916
|
+
ctx.dim = $.dim.bind(ctx);
|
|
4917
|
+
ctx.italic = $.italic.bind(ctx);
|
|
4918
|
+
ctx.underline = $.underline.bind(ctx);
|
|
4919
|
+
ctx.inverse = $.inverse.bind(ctx);
|
|
4920
|
+
ctx.hidden = $.hidden.bind(ctx);
|
|
4921
|
+
ctx.strikethrough = $.strikethrough.bind(ctx);
|
|
4922
|
+
ctx.black = $.black.bind(ctx);
|
|
4923
|
+
ctx.red = $.red.bind(ctx);
|
|
4924
|
+
ctx.green = $.green.bind(ctx);
|
|
4925
|
+
ctx.yellow = $.yellow.bind(ctx);
|
|
4926
|
+
ctx.blue = $.blue.bind(ctx);
|
|
4927
|
+
ctx.magenta = $.magenta.bind(ctx);
|
|
4928
|
+
ctx.cyan = $.cyan.bind(ctx);
|
|
4929
|
+
ctx.white = $.white.bind(ctx);
|
|
4930
|
+
ctx.gray = $.gray.bind(ctx);
|
|
4931
|
+
ctx.grey = $.grey.bind(ctx);
|
|
4932
|
+
ctx.bgBlack = $.bgBlack.bind(ctx);
|
|
4933
|
+
ctx.bgRed = $.bgRed.bind(ctx);
|
|
4934
|
+
ctx.bgGreen = $.bgGreen.bind(ctx);
|
|
4935
|
+
ctx.bgYellow = $.bgYellow.bind(ctx);
|
|
4936
|
+
ctx.bgBlue = $.bgBlue.bind(ctx);
|
|
4937
|
+
ctx.bgMagenta = $.bgMagenta.bind(ctx);
|
|
4938
|
+
ctx.bgCyan = $.bgCyan.bind(ctx);
|
|
4939
|
+
ctx.bgWhite = $.bgWhite.bind(ctx);
|
|
4940
|
+
return ctx;
|
|
4941
|
+
}
|
|
4942
|
+
function init(open, close) {
|
|
4943
|
+
let blk = {
|
|
4944
|
+
open: `\x1B[${open}m`,
|
|
4945
|
+
close: `\x1B[${close}m`,
|
|
4946
|
+
rgx: new RegExp(`\\x1b\\[${close}m`, "g")
|
|
4947
|
+
};
|
|
4948
|
+
return function(txt) {
|
|
4949
|
+
if (this !== void 0 && this.has !== void 0) {
|
|
4950
|
+
!!~this.has.indexOf(open) || (this.has.push(open), this.keys.push(blk));
|
|
4951
|
+
return txt === void 0 ? this : $.enabled ? run(this.keys, txt + "") : txt + "";
|
|
4952
|
+
}
|
|
4953
|
+
return txt === void 0 ? chain([open], [blk]) : $.enabled ? run([blk], txt + "") : txt + "";
|
|
4954
|
+
};
|
|
4955
|
+
}
|
|
4956
|
+
|
|
4957
|
+
// src/utils.ts
|
|
4958
|
+
function home(...parts) {
|
|
4959
|
+
return join2(homedir2(), ...parts);
|
|
4960
|
+
}
|
|
4961
|
+
function ensureDirFor(filePath) {
|
|
4962
|
+
const dir = dirname(filePath);
|
|
4963
|
+
if (!existsSync2(dir)) mkdirSync2(dir, { recursive: true });
|
|
4964
|
+
}
|
|
4965
|
+
|
|
4966
|
+
// src/hooks/runtime/repo-link-cache.ts
|
|
4967
|
+
var POSITIVE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
4968
|
+
var NEGATIVE_TTL_MS = 15 * 60 * 1e3;
|
|
4969
|
+
function repoLinkCachePath() {
|
|
4970
|
+
return home(".cybedefend", "repo-links.json");
|
|
4971
|
+
}
|
|
4972
|
+
function pathOf(deps) {
|
|
4973
|
+
return deps.cachePath ?? repoLinkCachePath();
|
|
4974
|
+
}
|
|
4975
|
+
function readRepoLinkCache(deps = {}) {
|
|
4976
|
+
const p = pathOf(deps);
|
|
4977
|
+
if (!existsSync3(p)) return {};
|
|
4978
|
+
try {
|
|
4979
|
+
const raw = readFileSync3(p, "utf8");
|
|
4980
|
+
if (!raw.trim()) return {};
|
|
4981
|
+
const parsed = JSON.parse(raw);
|
|
4982
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
4983
|
+
return parsed;
|
|
4984
|
+
}
|
|
4985
|
+
return {};
|
|
4986
|
+
} catch {
|
|
4987
|
+
return {};
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
function getCachedRepoLink(key, deps = {}) {
|
|
4991
|
+
const now = deps.now ?? Date.now;
|
|
4992
|
+
const entry = readRepoLinkCache(deps)[key];
|
|
4993
|
+
if (!entry || typeof entry !== "object") return { kind: "miss" };
|
|
4994
|
+
const resolvedAt = entry.resolvedAt;
|
|
4995
|
+
if (typeof resolvedAt !== "number") return { kind: "miss" };
|
|
4996
|
+
const age = now() - resolvedAt;
|
|
4997
|
+
if (age < 0) return { kind: "miss" };
|
|
4998
|
+
if (entry.negative === true) {
|
|
4999
|
+
return age < NEGATIVE_TTL_MS ? { kind: "negative" } : { kind: "miss" };
|
|
5000
|
+
}
|
|
5001
|
+
const pos = entry;
|
|
5002
|
+
if (typeof pos.projectId !== "string" || pos.projectId.length === 0) {
|
|
5003
|
+
return { kind: "miss" };
|
|
5004
|
+
}
|
|
5005
|
+
if (age < POSITIVE_TTL_MS) {
|
|
5006
|
+
return {
|
|
5007
|
+
kind: "positive",
|
|
5008
|
+
projectId: pos.projectId,
|
|
5009
|
+
// Missing → treated as enabled; only explicit `false` disables.
|
|
5010
|
+
vibedefendEnabled: pos.vibedefendEnabled !== false
|
|
5011
|
+
};
|
|
5012
|
+
}
|
|
5013
|
+
return { kind: "miss" };
|
|
5014
|
+
}
|
|
5015
|
+
function writeCachedRepoLink(key, entry, deps = {}) {
|
|
5016
|
+
const now = deps.now ?? Date.now;
|
|
5017
|
+
try {
|
|
5018
|
+
const map = readRepoLinkCache(deps);
|
|
5019
|
+
map[key] = "negative" in entry ? { negative: true, resolvedAt: now() } : {
|
|
5020
|
+
projectId: entry.projectId,
|
|
5021
|
+
vibedefendEnabled: entry.vibedefendEnabled,
|
|
5022
|
+
resolvedAt: now()
|
|
5023
|
+
};
|
|
5024
|
+
const p = pathOf(deps);
|
|
5025
|
+
const dir = dirname2(p);
|
|
5026
|
+
if (!existsSync3(dir)) mkdirSync3(dir, { recursive: true });
|
|
5027
|
+
writeFileSync3(p, JSON.stringify(map, null, 2) + "\n");
|
|
5028
|
+
} catch {
|
|
5029
|
+
}
|
|
5030
|
+
}
|
|
5031
|
+
|
|
5032
|
+
// src/hooks/runtime/config.ts
|
|
5033
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
|
|
5034
|
+
import { homedir as homedir3 } from "node:os";
|
|
5035
|
+
import { join as join3 } from "node:path";
|
|
5036
|
+
function runtimeConfigPath() {
|
|
5037
|
+
return join3(homedir3(), ".cybedefend", "runtime-config.json");
|
|
5038
|
+
}
|
|
5039
|
+
function loadRuntimeConfig(path) {
|
|
5040
|
+
const p = path ?? runtimeConfigPath();
|
|
5041
|
+
if (!existsSync4(p)) return null;
|
|
5042
|
+
try {
|
|
5043
|
+
const raw = readFileSync4(p, "utf8");
|
|
5044
|
+
return JSON.parse(raw);
|
|
5045
|
+
} catch {
|
|
5046
|
+
return null;
|
|
5047
|
+
}
|
|
5048
|
+
}
|
|
5049
|
+
async function readStdinJson() {
|
|
5050
|
+
const chunks = [];
|
|
5051
|
+
for await (const chunk of process.stdin) {
|
|
5052
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
5053
|
+
}
|
|
5054
|
+
const raw = Buffer.concat(chunks).toString("utf8");
|
|
5055
|
+
if (!raw.trim()) return {};
|
|
5056
|
+
try {
|
|
5057
|
+
const parsed = JSON.parse(raw);
|
|
5058
|
+
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
5059
|
+
} catch {
|
|
5060
|
+
return {};
|
|
5061
|
+
}
|
|
5062
|
+
}
|
|
5063
|
+
|
|
4745
5064
|
// src/hooks/runtime/resolve.ts
|
|
4746
5065
|
function resolveProjectId(cwd = process.cwd()) {
|
|
4747
5066
|
const envProjectId = process.env.CYBEDEFEND_PROJECT_ID;
|
|
@@ -4749,9 +5068,9 @@ function resolveProjectId(cwd = process.cwd()) {
|
|
|
4749
5068
|
return { projectId: envProjectId, apiBase: null };
|
|
4750
5069
|
}
|
|
4751
5070
|
const configPath = `${cwd}/.cybedefend/config.json`;
|
|
4752
|
-
if (
|
|
5071
|
+
if (existsSync5(configPath)) {
|
|
4753
5072
|
try {
|
|
4754
|
-
const raw =
|
|
5073
|
+
const raw = readFileSync5(configPath, "utf8");
|
|
4755
5074
|
const cfg = JSON.parse(raw);
|
|
4756
5075
|
return {
|
|
4757
5076
|
projectId: cfg.projectId ?? null,
|
|
@@ -4865,6 +5184,54 @@ async function resolveTokenWithRefresh(mcpName, deps = {}) {
|
|
|
4865
5184
|
}
|
|
4866
5185
|
return resolveTokenFn(mcpName);
|
|
4867
5186
|
}
|
|
5187
|
+
var RESOLVE_API_TIMEOUT_MS = 4e3;
|
|
5188
|
+
async function resolveProjectIdWithApi(cwd = process.cwd(), deps = {}) {
|
|
5189
|
+
const resolveSync = deps.resolveSync ?? resolveProjectId;
|
|
5190
|
+
const base = resolveSync(cwd);
|
|
5191
|
+
if (base.projectId) return base;
|
|
5192
|
+
try {
|
|
5193
|
+
const getOrigin = deps.getOrigin ?? getOriginRemote;
|
|
5194
|
+
const originUrl = getOrigin(cwd);
|
|
5195
|
+
if (!originUrl) return base;
|
|
5196
|
+
const remote = parseRemoteUrl(originUrl);
|
|
5197
|
+
if (!remote || remote.provider === null) return base;
|
|
5198
|
+
const key = `${remote.provider}:${remote.host}:${remote.slug}`;
|
|
5199
|
+
const cached = getCachedRepoLink(key, deps.cacheDeps);
|
|
5200
|
+
if (cached.kind === "positive") {
|
|
5201
|
+
return { projectId: cached.projectId, apiBase: base.apiBase };
|
|
5202
|
+
}
|
|
5203
|
+
if (cached.kind === "negative") {
|
|
5204
|
+
return base;
|
|
5205
|
+
}
|
|
5206
|
+
const config = (deps.loadConfig ?? loadRuntimeConfig)();
|
|
5207
|
+
if (!config) return base;
|
|
5208
|
+
const apiBase = base.apiBase ?? config.region.apiBase;
|
|
5209
|
+
const resolveTokenFn = deps.resolveTokenFn ?? resolveTokenWithRefresh;
|
|
5210
|
+
const token = await resolveTokenFn(config.region.mcpName);
|
|
5211
|
+
if (!token) return base;
|
|
5212
|
+
const resolveByRepo = deps.resolveByRepo ?? resolveProjectByRepository;
|
|
5213
|
+
const matches = await resolveByRepo(
|
|
5214
|
+
apiBase,
|
|
5215
|
+
token,
|
|
5216
|
+
{ provider: remote.provider, slug: remote.slug, host: remote.host },
|
|
5217
|
+
{ timeoutMs: deps.timeoutMs ?? RESOLVE_API_TIMEOUT_MS }
|
|
5218
|
+
);
|
|
5219
|
+
if (matches === null) return base;
|
|
5220
|
+
if (matches.length === 1 && matches[0].vibedefendEnabled !== false) {
|
|
5221
|
+
const m = matches[0];
|
|
5222
|
+
writeCachedRepoLink(
|
|
5223
|
+
key,
|
|
5224
|
+
{ projectId: m.projectId, vibedefendEnabled: m.vibedefendEnabled },
|
|
5225
|
+
deps.cacheDeps
|
|
5226
|
+
);
|
|
5227
|
+
return { projectId: m.projectId, apiBase: base.apiBase };
|
|
5228
|
+
}
|
|
5229
|
+
writeCachedRepoLink(key, { negative: true }, deps.cacheDeps);
|
|
5230
|
+
return base;
|
|
5231
|
+
} catch {
|
|
5232
|
+
return base;
|
|
5233
|
+
}
|
|
5234
|
+
}
|
|
4868
5235
|
|
|
4869
5236
|
// src/hooks/runtime/api.ts
|
|
4870
5237
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
@@ -5006,38 +5373,6 @@ function emitStop(body, client, reason) {
|
|
|
5006
5373
|
emit(body, client);
|
|
5007
5374
|
}
|
|
5008
5375
|
|
|
5009
|
-
// src/hooks/runtime/config.ts
|
|
5010
|
-
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
|
|
5011
|
-
import { homedir as homedir2 } from "node:os";
|
|
5012
|
-
import { join as join2 } from "node:path";
|
|
5013
|
-
function runtimeConfigPath() {
|
|
5014
|
-
return join2(homedir2(), ".cybedefend", "runtime-config.json");
|
|
5015
|
-
}
|
|
5016
|
-
function loadRuntimeConfig(path) {
|
|
5017
|
-
const p = path ?? runtimeConfigPath();
|
|
5018
|
-
if (!existsSync3(p)) return null;
|
|
5019
|
-
try {
|
|
5020
|
-
const raw = readFileSync3(p, "utf8");
|
|
5021
|
-
return JSON.parse(raw);
|
|
5022
|
-
} catch {
|
|
5023
|
-
return null;
|
|
5024
|
-
}
|
|
5025
|
-
}
|
|
5026
|
-
async function readStdinJson() {
|
|
5027
|
-
const chunks = [];
|
|
5028
|
-
for await (const chunk of process.stdin) {
|
|
5029
|
-
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
5030
|
-
}
|
|
5031
|
-
const raw = Buffer.concat(chunks).toString("utf8");
|
|
5032
|
-
if (!raw.trim()) return {};
|
|
5033
|
-
try {
|
|
5034
|
-
const parsed = JSON.parse(raw);
|
|
5035
|
-
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
5036
|
-
} catch {
|
|
5037
|
-
return {};
|
|
5038
|
-
}
|
|
5039
|
-
}
|
|
5040
|
-
|
|
5041
5376
|
// src/hooks/runtime/fetch-rules.ts
|
|
5042
5377
|
var INTERESTED_TOOLS = /* @__PURE__ */ new Set([
|
|
5043
5378
|
"Edit",
|
|
@@ -5048,7 +5383,7 @@ var INTERESTED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
5048
5383
|
async function fetchRulesHook(deps = {}) {
|
|
5049
5384
|
const readStdin = deps.readStdin ?? readStdinJson;
|
|
5050
5385
|
const loadConfig = deps.loadConfig ?? loadRuntimeConfig;
|
|
5051
|
-
const resolveProject = deps.resolveProject ??
|
|
5386
|
+
const resolveProject = deps.resolveProject ?? resolveProjectIdWithApi;
|
|
5052
5387
|
const resolveTok = deps.resolveTokenFn ?? resolveToken;
|
|
5053
5388
|
const fetchRules = deps.fetchRulesFn ?? fetchBusinessRules;
|
|
5054
5389
|
const fetchSecRules = deps.fetchSecurityRulesFn ?? fetchSecurityRules;
|
|
@@ -5059,7 +5394,7 @@ async function fetchRulesHook(deps = {}) {
|
|
|
5059
5394
|
if (!event.filePath) return;
|
|
5060
5395
|
const config = loadConfig();
|
|
5061
5396
|
if (!config) return;
|
|
5062
|
-
const { projectId, apiBase: configApiBase } = resolveProject();
|
|
5397
|
+
const { projectId, apiBase: configApiBase } = await resolveProject();
|
|
5063
5398
|
if (!projectId) return;
|
|
5064
5399
|
const apiBase = process.env.CYBEDEFEND_API_BASE ?? configApiBase ?? config.region.apiBase;
|
|
5065
5400
|
const token = resolveTok(config.region.mcpName);
|
|
@@ -5152,119 +5487,10 @@ function composeSecurityBody(markdown, total, filePath) {
|
|
|
5152
5487
|
|
|
5153
5488
|
// src/hooks/runtime/self-update-check.ts
|
|
5154
5489
|
import { spawn } from "node:child_process";
|
|
5155
|
-
import { existsSync as
|
|
5156
|
-
import { homedir as
|
|
5490
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6, rmSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
5491
|
+
import { homedir as homedir4 } from "node:os";
|
|
5157
5492
|
import { join as join4 } from "node:path";
|
|
5158
5493
|
|
|
5159
|
-
// src/utils.ts
|
|
5160
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
5161
|
-
import { dirname, join as join3 } from "node:path";
|
|
5162
|
-
|
|
5163
|
-
// node_modules/.pnpm/kleur@4.1.5/node_modules/kleur/index.mjs
|
|
5164
|
-
var FORCE_COLOR;
|
|
5165
|
-
var NODE_DISABLE_COLORS;
|
|
5166
|
-
var NO_COLOR;
|
|
5167
|
-
var TERM;
|
|
5168
|
-
var isTTY = true;
|
|
5169
|
-
if (typeof process !== "undefined") {
|
|
5170
|
-
({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
|
|
5171
|
-
isTTY = process.stdout && process.stdout.isTTY;
|
|
5172
|
-
}
|
|
5173
|
-
var $ = {
|
|
5174
|
-
enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY),
|
|
5175
|
-
// modifiers
|
|
5176
|
-
reset: init(0, 0),
|
|
5177
|
-
bold: init(1, 22),
|
|
5178
|
-
dim: init(2, 22),
|
|
5179
|
-
italic: init(3, 23),
|
|
5180
|
-
underline: init(4, 24),
|
|
5181
|
-
inverse: init(7, 27),
|
|
5182
|
-
hidden: init(8, 28),
|
|
5183
|
-
strikethrough: init(9, 29),
|
|
5184
|
-
// colors
|
|
5185
|
-
black: init(30, 39),
|
|
5186
|
-
red: init(31, 39),
|
|
5187
|
-
green: init(32, 39),
|
|
5188
|
-
yellow: init(33, 39),
|
|
5189
|
-
blue: init(34, 39),
|
|
5190
|
-
magenta: init(35, 39),
|
|
5191
|
-
cyan: init(36, 39),
|
|
5192
|
-
white: init(37, 39),
|
|
5193
|
-
gray: init(90, 39),
|
|
5194
|
-
grey: init(90, 39),
|
|
5195
|
-
// background colors
|
|
5196
|
-
bgBlack: init(40, 49),
|
|
5197
|
-
bgRed: init(41, 49),
|
|
5198
|
-
bgGreen: init(42, 49),
|
|
5199
|
-
bgYellow: init(43, 49),
|
|
5200
|
-
bgBlue: init(44, 49),
|
|
5201
|
-
bgMagenta: init(45, 49),
|
|
5202
|
-
bgCyan: init(46, 49),
|
|
5203
|
-
bgWhite: init(47, 49)
|
|
5204
|
-
};
|
|
5205
|
-
function run(arr, str) {
|
|
5206
|
-
let i = 0, tmp, beg = "", end = "";
|
|
5207
|
-
for (; i < arr.length; i++) {
|
|
5208
|
-
tmp = arr[i];
|
|
5209
|
-
beg += tmp.open;
|
|
5210
|
-
end += tmp.close;
|
|
5211
|
-
if (!!~str.indexOf(tmp.close)) {
|
|
5212
|
-
str = str.replace(tmp.rgx, tmp.close + tmp.open);
|
|
5213
|
-
}
|
|
5214
|
-
}
|
|
5215
|
-
return beg + str + end;
|
|
5216
|
-
}
|
|
5217
|
-
function chain(has, keys) {
|
|
5218
|
-
let ctx = { has, keys };
|
|
5219
|
-
ctx.reset = $.reset.bind(ctx);
|
|
5220
|
-
ctx.bold = $.bold.bind(ctx);
|
|
5221
|
-
ctx.dim = $.dim.bind(ctx);
|
|
5222
|
-
ctx.italic = $.italic.bind(ctx);
|
|
5223
|
-
ctx.underline = $.underline.bind(ctx);
|
|
5224
|
-
ctx.inverse = $.inverse.bind(ctx);
|
|
5225
|
-
ctx.hidden = $.hidden.bind(ctx);
|
|
5226
|
-
ctx.strikethrough = $.strikethrough.bind(ctx);
|
|
5227
|
-
ctx.black = $.black.bind(ctx);
|
|
5228
|
-
ctx.red = $.red.bind(ctx);
|
|
5229
|
-
ctx.green = $.green.bind(ctx);
|
|
5230
|
-
ctx.yellow = $.yellow.bind(ctx);
|
|
5231
|
-
ctx.blue = $.blue.bind(ctx);
|
|
5232
|
-
ctx.magenta = $.magenta.bind(ctx);
|
|
5233
|
-
ctx.cyan = $.cyan.bind(ctx);
|
|
5234
|
-
ctx.white = $.white.bind(ctx);
|
|
5235
|
-
ctx.gray = $.gray.bind(ctx);
|
|
5236
|
-
ctx.grey = $.grey.bind(ctx);
|
|
5237
|
-
ctx.bgBlack = $.bgBlack.bind(ctx);
|
|
5238
|
-
ctx.bgRed = $.bgRed.bind(ctx);
|
|
5239
|
-
ctx.bgGreen = $.bgGreen.bind(ctx);
|
|
5240
|
-
ctx.bgYellow = $.bgYellow.bind(ctx);
|
|
5241
|
-
ctx.bgBlue = $.bgBlue.bind(ctx);
|
|
5242
|
-
ctx.bgMagenta = $.bgMagenta.bind(ctx);
|
|
5243
|
-
ctx.bgCyan = $.bgCyan.bind(ctx);
|
|
5244
|
-
ctx.bgWhite = $.bgWhite.bind(ctx);
|
|
5245
|
-
return ctx;
|
|
5246
|
-
}
|
|
5247
|
-
function init(open, close) {
|
|
5248
|
-
let blk = {
|
|
5249
|
-
open: `\x1B[${open}m`,
|
|
5250
|
-
close: `\x1B[${close}m`,
|
|
5251
|
-
rgx: new RegExp(`\\x1b\\[${close}m`, "g")
|
|
5252
|
-
};
|
|
5253
|
-
return function(txt) {
|
|
5254
|
-
if (this !== void 0 && this.has !== void 0) {
|
|
5255
|
-
!!~this.has.indexOf(open) || (this.has.push(open), this.keys.push(blk));
|
|
5256
|
-
return txt === void 0 ? this : $.enabled ? run(this.keys, txt + "") : txt + "";
|
|
5257
|
-
}
|
|
5258
|
-
return txt === void 0 ? chain([open], [blk]) : $.enabled ? run([blk], txt + "") : txt + "";
|
|
5259
|
-
};
|
|
5260
|
-
}
|
|
5261
|
-
|
|
5262
|
-
// src/utils.ts
|
|
5263
|
-
function ensureDirFor(filePath) {
|
|
5264
|
-
const dir = dirname(filePath);
|
|
5265
|
-
if (!existsSync4(dir)) mkdirSync2(dir, { recursive: true });
|
|
5266
|
-
}
|
|
5267
|
-
|
|
5268
5494
|
// src/hooks/runtime/semver.ts
|
|
5269
5495
|
function parseVersion(input) {
|
|
5270
5496
|
const cleaned = input.trim().replace(/^v/i, "");
|
|
@@ -5291,7 +5517,7 @@ function isNewer(latest, current) {
|
|
|
5291
5517
|
|
|
5292
5518
|
// src/self-update.ts
|
|
5293
5519
|
import { fileURLToPath } from "node:url";
|
|
5294
|
-
import { existsSync as
|
|
5520
|
+
import { existsSync as existsSync6, realpathSync } from "node:fs";
|
|
5295
5521
|
var GLOBAL_MODES = /* @__PURE__ */ new Set([
|
|
5296
5522
|
"npm-global",
|
|
5297
5523
|
"pnpm-global",
|
|
@@ -5318,7 +5544,7 @@ function detectInstallMode(scriptPath) {
|
|
|
5318
5544
|
}
|
|
5319
5545
|
function resolveScriptPath() {
|
|
5320
5546
|
const fromArgv = process.argv[1];
|
|
5321
|
-
if (fromArgv &&
|
|
5547
|
+
if (fromArgv && existsSync6(fromArgv)) {
|
|
5322
5548
|
try {
|
|
5323
5549
|
return realpathSync(fromArgv);
|
|
5324
5550
|
} catch {
|
|
@@ -5335,7 +5561,7 @@ var THROTTLE_MS = 24 * 60 * 60 * 1e3;
|
|
|
5335
5561
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
5336
5562
|
async function selfUpdateCheck(deps) {
|
|
5337
5563
|
const now = deps.now ?? (() => Date.now());
|
|
5338
|
-
const dir = deps.cybeDir ?? join4(process.env.CYBEDEFEND_HOME ??
|
|
5564
|
+
const dir = deps.cybeDir ?? join4(process.env.CYBEDEFEND_HOME ?? homedir4(), ".cybedefend");
|
|
5339
5565
|
const throttlePath = join4(dir, "update-check.json");
|
|
5340
5566
|
const logPath = join4(dir, "last-update.log");
|
|
5341
5567
|
const installMode = deps.installMode ?? (deps.runnerSource ? detectInstallMode(deps.runnerSource) : detectInstallMode(resolveScriptPath()));
|
|
@@ -5370,8 +5596,8 @@ function applyOrNotify(deps, installMode, latest, logPath) {
|
|
|
5370
5596
|
}
|
|
5371
5597
|
function readThrottle(path) {
|
|
5372
5598
|
try {
|
|
5373
|
-
if (!
|
|
5374
|
-
const data = JSON.parse(
|
|
5599
|
+
if (!existsSync7(path)) return null;
|
|
5600
|
+
const data = JSON.parse(readFileSync6(path, "utf8"));
|
|
5375
5601
|
if (typeof data.lastCheckedAt !== "number") return null;
|
|
5376
5602
|
return { lastCheckedAt: data.lastCheckedAt };
|
|
5377
5603
|
} catch {
|
|
@@ -5381,16 +5607,16 @@ function readThrottle(path) {
|
|
|
5381
5607
|
function writeThrottle(path, throttle) {
|
|
5382
5608
|
try {
|
|
5383
5609
|
ensureDirFor(path);
|
|
5384
|
-
|
|
5610
|
+
writeFileSync4(path, JSON.stringify(throttle) + "\n");
|
|
5385
5611
|
} catch {
|
|
5386
5612
|
}
|
|
5387
5613
|
}
|
|
5388
5614
|
function takeUpdateLogNotice(logPath) {
|
|
5389
5615
|
try {
|
|
5390
|
-
if (!
|
|
5616
|
+
if (!existsSync7(logPath)) return null;
|
|
5391
5617
|
let parsed = {};
|
|
5392
5618
|
try {
|
|
5393
|
-
parsed = JSON.parse(
|
|
5619
|
+
parsed = JSON.parse(readFileSync6(logPath, "utf8"));
|
|
5394
5620
|
} catch {
|
|
5395
5621
|
parsed = {};
|
|
5396
5622
|
}
|
|
@@ -5464,18 +5690,18 @@ function pmCommand(mode, spec) {
|
|
|
5464
5690
|
}
|
|
5465
5691
|
|
|
5466
5692
|
// src/version.ts
|
|
5467
|
-
import { readFileSync as
|
|
5693
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
5468
5694
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
5469
|
-
import { dirname as
|
|
5695
|
+
import { dirname as dirname3, join as join5 } from "node:path";
|
|
5470
5696
|
var PKG_NAME = "@cybedefend/vibedefend";
|
|
5471
5697
|
function defaultPkgPath() {
|
|
5472
|
-
return join5(
|
|
5698
|
+
return join5(dirname3(fileURLToPath2(import.meta.url)), "..", "package.json");
|
|
5473
5699
|
}
|
|
5474
5700
|
function readPackageMeta(opts = {}) {
|
|
5475
5701
|
if (typeof opts.bakedVersion === "string" && opts.bakedVersion.length > 0) {
|
|
5476
5702
|
return { name: PKG_NAME, version: opts.bakedVersion };
|
|
5477
5703
|
}
|
|
5478
|
-
const readFile = opts.readFile ?? ((p) =>
|
|
5704
|
+
const readFile = opts.readFile ?? ((p) => readFileSync7(p, "utf8"));
|
|
5479
5705
|
const pkgPath = opts.pkgPath ?? defaultPkgPath();
|
|
5480
5706
|
try {
|
|
5481
5707
|
return JSON.parse(readFile(pkgPath));
|
|
@@ -5484,14 +5710,14 @@ function readPackageMeta(opts = {}) {
|
|
|
5484
5710
|
}
|
|
5485
5711
|
}
|
|
5486
5712
|
var pkg = readPackageMeta({
|
|
5487
|
-
bakedVersion: true ? "1.
|
|
5713
|
+
bakedVersion: true ? "1.4.0" : void 0
|
|
5488
5714
|
});
|
|
5489
5715
|
|
|
5490
5716
|
// src/hooks/runtime/session-start.ts
|
|
5491
5717
|
async function sessionStartHook(deps = {}) {
|
|
5492
5718
|
const readStdin = deps.readStdin ?? readStdinJson;
|
|
5493
5719
|
const loadConfig = deps.loadConfig ?? loadRuntimeConfig;
|
|
5494
|
-
const resolveProject = deps.resolveProject ??
|
|
5720
|
+
const resolveProject = deps.resolveProject ?? resolveProjectIdWithApi;
|
|
5495
5721
|
const resolveTok = deps.resolveTokenFn ?? resolveToken;
|
|
5496
5722
|
const fetchProposals = deps.fetchProposalsFn ?? fetchProposalsCount;
|
|
5497
5723
|
const selfUpdateCheckFn = deps.selfUpdateCheckFn ?? selfUpdateCheck;
|
|
@@ -5500,7 +5726,7 @@ async function sessionStartHook(deps = {}) {
|
|
|
5500
5726
|
const event = sniff(stdin);
|
|
5501
5727
|
const config = loadConfig();
|
|
5502
5728
|
if (!config) return;
|
|
5503
|
-
const { projectId, apiBase: configApiBase } = resolveProject();
|
|
5729
|
+
const { projectId, apiBase: configApiBase } = await resolveProject();
|
|
5504
5730
|
if (!projectId) return;
|
|
5505
5731
|
const apiBase = process.env.CYBEDEFEND_API_BASE ?? configApiBase ?? config.region.apiBase;
|
|
5506
5732
|
if (process.env.CYBEDEFEND_DRY_RUN === "1") {
|
|
@@ -5586,7 +5812,7 @@ async function sessionStartHook(deps = {}) {
|
|
|
5586
5812
|
}
|
|
5587
5813
|
|
|
5588
5814
|
// src/hooks/runtime/session-review.ts
|
|
5589
|
-
import { existsSync as
|
|
5815
|
+
import { existsSync as existsSync8, readFileSync as readFileSync8 } from "node:fs";
|
|
5590
5816
|
var COUNTED_TOOLS = /* @__PURE__ */ new Set([
|
|
5591
5817
|
"Edit",
|
|
5592
5818
|
"Write",
|
|
@@ -5664,9 +5890,9 @@ function loadTranscript(stdin, readFile) {
|
|
|
5664
5890
|
return out;
|
|
5665
5891
|
}
|
|
5666
5892
|
function defaultReadTranscript(path) {
|
|
5667
|
-
if (!
|
|
5893
|
+
if (!existsSync8(path)) return null;
|
|
5668
5894
|
try {
|
|
5669
|
-
return
|
|
5895
|
+
return readFileSync8(path, "utf8");
|
|
5670
5896
|
} catch {
|
|
5671
5897
|
return null;
|
|
5672
5898
|
}
|
|
@@ -5734,10 +5960,12 @@ function collectChangedFilesDeep(node, depth, out) {
|
|
|
5734
5960
|
}
|
|
5735
5961
|
}
|
|
5736
5962
|
function relativizePath(p, cwd) {
|
|
5737
|
-
|
|
5738
|
-
|
|
5963
|
+
const np = p.replace(/\\/g, "/");
|
|
5964
|
+
const nc = cwd.replace(/\\/g, "/");
|
|
5965
|
+
if (nc && np.startsWith(nc.endsWith("/") ? nc : nc + "/")) {
|
|
5966
|
+
return np.slice(nc.endsWith("/") ? nc.length : nc.length + 1);
|
|
5739
5967
|
}
|
|
5740
|
-
return
|
|
5968
|
+
return np;
|
|
5741
5969
|
}
|
|
5742
5970
|
function extractChangedFiles(transcript, cap = CHANGED_FILES_MAX, cwd) {
|
|
5743
5971
|
const out = /* @__PURE__ */ new Set();
|
|
@@ -5922,19 +6150,19 @@ async function preCompactHook(deps = {}) {
|
|
|
5922
6150
|
}
|
|
5923
6151
|
|
|
5924
6152
|
// src/hooks/runtime/user-prompt-submit.ts
|
|
5925
|
-
import { existsSync as
|
|
5926
|
-
import { homedir as
|
|
6153
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "node:fs";
|
|
6154
|
+
import { homedir as homedir5 } from "node:os";
|
|
5927
6155
|
import { join as join6 } from "node:path";
|
|
5928
6156
|
var SESSIONS_CAP = 100;
|
|
5929
6157
|
function defaultSessionsFile() {
|
|
5930
|
-
const dir = process.env.CYBEDEFEND_BASELINE_DIR ?? join6(
|
|
6158
|
+
const dir = process.env.CYBEDEFEND_BASELINE_DIR ?? join6(homedir5(), ".cybedefend");
|
|
5931
6159
|
return join6(dir, "user-prompt-seen-sessions.json");
|
|
5932
6160
|
}
|
|
5933
6161
|
function defaultSessionTracker(file = defaultSessionsFile()) {
|
|
5934
6162
|
function load() {
|
|
5935
|
-
if (!
|
|
6163
|
+
if (!existsSync9(file)) return [];
|
|
5936
6164
|
try {
|
|
5937
|
-
const raw =
|
|
6165
|
+
const raw = readFileSync9(file, "utf8");
|
|
5938
6166
|
const data = JSON.parse(raw);
|
|
5939
6167
|
if (!Array.isArray(data.sessions)) return [];
|
|
5940
6168
|
return data.sessions.filter((s) => typeof s === "string");
|
|
@@ -5951,8 +6179,8 @@ function defaultSessionTracker(file = defaultSessionsFile()) {
|
|
|
5951
6179
|
if (existing.includes(sessionId)) return;
|
|
5952
6180
|
const next = [...existing, sessionId].slice(-SESSIONS_CAP);
|
|
5953
6181
|
try {
|
|
5954
|
-
|
|
5955
|
-
|
|
6182
|
+
mkdirSync4(join6(file, ".."), { recursive: true });
|
|
6183
|
+
writeFileSync5(file, JSON.stringify({ sessions: next }), "utf8");
|
|
5956
6184
|
} catch {
|
|
5957
6185
|
}
|
|
5958
6186
|
}
|
|
@@ -5961,7 +6189,7 @@ function defaultSessionTracker(file = defaultSessionsFile()) {
|
|
|
5961
6189
|
async function userPromptSubmitHook(deps = {}) {
|
|
5962
6190
|
const readStdin = deps.readStdin ?? readStdinJson;
|
|
5963
6191
|
const loadConfig = deps.loadConfig ?? loadRuntimeConfig;
|
|
5964
|
-
const resolveProject = deps.resolveProject ??
|
|
6192
|
+
const resolveProject = deps.resolveProject ?? resolveProjectIdWithApi;
|
|
5965
6193
|
const resolveTok = deps.resolveTokenFn ?? resolveToken;
|
|
5966
6194
|
const fetchProposals = deps.fetchProposalsFn ?? fetchProposalsCount;
|
|
5967
6195
|
const emitFn = deps.emitFn ?? emit;
|
|
@@ -5974,7 +6202,7 @@ async function userPromptSubmitHook(deps = {}) {
|
|
|
5974
6202
|
}
|
|
5975
6203
|
const config = loadConfig();
|
|
5976
6204
|
if (!config) return;
|
|
5977
|
-
const { projectId, apiBase: configApiBase } = resolveProject();
|
|
6205
|
+
const { projectId, apiBase: configApiBase } = await resolveProject();
|
|
5978
6206
|
if (!projectId) return;
|
|
5979
6207
|
const apiBase = process.env.CYBEDEFEND_API_BASE ?? configApiBase ?? config.region.apiBase;
|
|
5980
6208
|
const token = resolveTok(config.region.mcpName);
|
|
@@ -6780,7 +7008,7 @@ function nearMissCommand(target, rule) {
|
|
|
6780
7008
|
function nearMissFile(target, rule, homeDir) {
|
|
6781
7009
|
const globs = rule.filePathGlobs;
|
|
6782
7010
|
if (!globs || globs.length === 0) return false;
|
|
6783
|
-
const path = expandTilde(target.path, homeDir);
|
|
7011
|
+
const path = expandTilde(target.path, homeDir).replace(/\\/g, "/");
|
|
6784
7012
|
const base = basename(path);
|
|
6785
7013
|
const segs = path.split("/");
|
|
6786
7014
|
for (const g of globs) {
|
|
@@ -6871,12 +7099,12 @@ function nearMiss(req, rule) {
|
|
|
6871
7099
|
}
|
|
6872
7100
|
|
|
6873
7101
|
// src/hooks/runtime/guard-rules-cache.ts
|
|
6874
|
-
import { readFileSync as
|
|
6875
|
-
import { dirname as
|
|
6876
|
-
import { homedir as
|
|
7102
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, existsSync as existsSync10, mkdirSync as mkdirSync5 } from "node:fs";
|
|
7103
|
+
import { dirname as dirname4 } from "node:path";
|
|
7104
|
+
import { homedir as homedir6 } from "node:os";
|
|
6877
7105
|
import { join as join7 } from "node:path";
|
|
6878
7106
|
var DEFAULT_CACHE_FILE = join7(
|
|
6879
|
-
|
|
7107
|
+
homedir6(),
|
|
6880
7108
|
".cybedefend",
|
|
6881
7109
|
"guards-cache.json"
|
|
6882
7110
|
);
|
|
@@ -6974,9 +7202,9 @@ function makeGuardRulesCache(opts) {
|
|
|
6974
7202
|
}
|
|
6975
7203
|
}
|
|
6976
7204
|
function readCache(projectId) {
|
|
6977
|
-
if (!
|
|
7205
|
+
if (!existsSync10(cacheFile)) return null;
|
|
6978
7206
|
try {
|
|
6979
|
-
const raw =
|
|
7207
|
+
const raw = readFileSync10(cacheFile, "utf8");
|
|
6980
7208
|
const data = JSON.parse(raw);
|
|
6981
7209
|
if (data.projectId !== projectId) return null;
|
|
6982
7210
|
return data;
|
|
@@ -6987,16 +7215,16 @@ function makeGuardRulesCache(opts) {
|
|
|
6987
7215
|
function writeCache(entry) {
|
|
6988
7216
|
try {
|
|
6989
7217
|
ensureDirFor2(cacheFile);
|
|
6990
|
-
|
|
7218
|
+
writeFileSync6(cacheFile, JSON.stringify(entry), "utf8");
|
|
6991
7219
|
} catch {
|
|
6992
7220
|
}
|
|
6993
7221
|
}
|
|
6994
7222
|
return { refreshIfStale };
|
|
6995
7223
|
}
|
|
6996
7224
|
function ensureDirFor2(filePath) {
|
|
6997
|
-
const dir =
|
|
6998
|
-
if (!
|
|
6999
|
-
|
|
7225
|
+
const dir = dirname4(filePath);
|
|
7226
|
+
if (!existsSync10(dir)) {
|
|
7227
|
+
mkdirSync5(dir, { recursive: true });
|
|
7000
7228
|
}
|
|
7001
7229
|
}
|
|
7002
7230
|
var DEFAULT_TIMEOUT_MS2 = 8e3;
|
|
@@ -7079,12 +7307,49 @@ async function callJudge(input, opts = {}) {
|
|
|
7079
7307
|
}
|
|
7080
7308
|
}
|
|
7081
7309
|
|
|
7310
|
+
// src/hooks/runtime/judge-injection.ts
|
|
7311
|
+
var SEP_RUN = /[.\-_/\\+,;\s]+/g;
|
|
7312
|
+
var SIGNALS = [
|
|
7313
|
+
// A1a — verdict assignment with '=': decision=allow, answer=allow
|
|
7314
|
+
/\b(decision|verdict|veredict|answer|result|output|response)\s*=\s*["']?(allow|block|approve|permit)\b/,
|
|
7315
|
+
// A1b — verdict with a space separator (covers decision.allow / -allow / _allow)
|
|
7316
|
+
/\b(decision|verdict)\s+["']?(allow|block)\b/,
|
|
7317
|
+
// A2 — literal JSON verdict shape: {"decision":"allow"}
|
|
7318
|
+
/["'](decision|verdict)["']\s*:\s*["'](allow|block)["']/,
|
|
7319
|
+
// A3 — imperative verdict directive: reply allow, respond with allow
|
|
7320
|
+
/\b(reply|respond|answer|say)\s+(with\s+|the\s+)?["']?(allow|block)\b/,
|
|
7321
|
+
// A4 — permission imperative: you may allow this
|
|
7322
|
+
/\byou\s+(must|should|may|can|are\s+to|need\s+to)\s+(allow|permit|approve|unblock)\b/,
|
|
7323
|
+
// A5 — mark-as-safe / do-not-block
|
|
7324
|
+
/\bmark(ed)?\s+(this|it)\s+(as\s+)?(safe|allowed|authori[sz]ed|approved)\b/,
|
|
7325
|
+
/\bdo\s*not\s+block\b/,
|
|
7326
|
+
/\bdon'?t\s+block\b/,
|
|
7327
|
+
// A6 — "let it/this pass|through|proceed" (the reported "laisse passer")
|
|
7328
|
+
/\blet\s+(it|this|the)\s+(command\s+|action\s+|tool\s+)?(pass|through|proceed)\b/,
|
|
7329
|
+
// B — rule/guard nullification: strong verbs + the control-object noun
|
|
7330
|
+
/\b(ignore|disregard|override|bypass|circumvent|nullify)\s+(the\s+|this\s+|all\s+|any\s+|previous\s+|above\s+|prior\s+)*(rule|rules|instruction|instructions|deny|denial|denies|policy|policies|check|checks|guard|guards|guardrail|guardrails|restriction|restrictions)\b/,
|
|
7331
|
+
// C — role/meta break-in
|
|
7332
|
+
/\b(you\s+are|as)\s+(the\s+|a\s+)?(security\s+)?(judge|reviewer|approver|arbiter)\b/,
|
|
7333
|
+
/\bnew\s+instructions?\b/,
|
|
7334
|
+
/<\s*\/?\s*(system|assistant|user|developer|tool)\b/
|
|
7335
|
+
];
|
|
7336
|
+
function normalize(text) {
|
|
7337
|
+
const folded = text.normalize("NFKC").toLowerCase();
|
|
7338
|
+
return folded.replace(SEP_RUN, " ").trim();
|
|
7339
|
+
}
|
|
7340
|
+
function detectPromptInjection(text) {
|
|
7341
|
+
if (!text) return false;
|
|
7342
|
+
const normalized = normalize(String(text));
|
|
7343
|
+
if (!normalized) return false;
|
|
7344
|
+
return SIGNALS.some((sig) => sig.test(normalized));
|
|
7345
|
+
}
|
|
7346
|
+
|
|
7082
7347
|
// src/hooks/runtime/judge-cache.ts
|
|
7083
|
-
import { readFileSync as
|
|
7084
|
-
import { dirname as
|
|
7085
|
-
import { homedir as
|
|
7348
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, existsSync as existsSync11, mkdirSync as mkdirSync6 } from "node:fs";
|
|
7349
|
+
import { dirname as dirname5, join as join8 } from "node:path";
|
|
7350
|
+
import { homedir as homedir7 } from "node:os";
|
|
7086
7351
|
var DEFAULT_JUDGE_CACHE_FILE = join8(
|
|
7087
|
-
|
|
7352
|
+
homedir7(),
|
|
7088
7353
|
".cybedefend",
|
|
7089
7354
|
"guards-judge-cache.json"
|
|
7090
7355
|
);
|
|
@@ -7094,9 +7359,9 @@ function makeJudgeCache(opts = {}) {
|
|
|
7094
7359
|
const ttlMs = opts.ttlMs ?? DEFAULT_JUDGE_TTL_MS;
|
|
7095
7360
|
const now = opts.now ?? (() => Date.now());
|
|
7096
7361
|
function readAll() {
|
|
7097
|
-
if (!
|
|
7362
|
+
if (!existsSync11(cacheFile)) return {};
|
|
7098
7363
|
try {
|
|
7099
|
-
return JSON.parse(
|
|
7364
|
+
return JSON.parse(readFileSync11(cacheFile, "utf8"));
|
|
7100
7365
|
} catch {
|
|
7101
7366
|
return {};
|
|
7102
7367
|
}
|
|
@@ -7116,36 +7381,36 @@ function makeJudgeCache(opts = {}) {
|
|
|
7116
7381
|
}
|
|
7117
7382
|
all[key] = { res, at: t };
|
|
7118
7383
|
ensureDirFor3(cacheFile);
|
|
7119
|
-
|
|
7384
|
+
writeFileSync7(cacheFile, JSON.stringify(all), "utf8");
|
|
7120
7385
|
} catch {
|
|
7121
7386
|
}
|
|
7122
7387
|
}
|
|
7123
7388
|
return { get, set };
|
|
7124
7389
|
}
|
|
7125
7390
|
function ensureDirFor3(filePath) {
|
|
7126
|
-
const dir =
|
|
7127
|
-
if (!
|
|
7128
|
-
|
|
7391
|
+
const dir = dirname5(filePath);
|
|
7392
|
+
if (!existsSync11(dir)) {
|
|
7393
|
+
mkdirSync6(dir, { recursive: true });
|
|
7129
7394
|
}
|
|
7130
7395
|
}
|
|
7131
7396
|
|
|
7132
7397
|
// src/hooks/runtime/guard-check.ts
|
|
7133
|
-
import { homedir as
|
|
7398
|
+
import { homedir as homedir9 } from "node:os";
|
|
7134
7399
|
import { join as join10 } from "node:path";
|
|
7135
7400
|
|
|
7136
7401
|
// src/hooks/runtime/guard-violations-buffer.ts
|
|
7137
7402
|
import {
|
|
7138
7403
|
appendFileSync,
|
|
7139
|
-
existsSync as
|
|
7140
|
-
readFileSync as
|
|
7141
|
-
writeFileSync as
|
|
7142
|
-
mkdirSync as
|
|
7404
|
+
existsSync as existsSync12,
|
|
7405
|
+
readFileSync as readFileSync12,
|
|
7406
|
+
writeFileSync as writeFileSync8,
|
|
7407
|
+
mkdirSync as mkdirSync7
|
|
7143
7408
|
} from "node:fs";
|
|
7144
|
-
import { dirname as
|
|
7145
|
-
import { homedir as
|
|
7409
|
+
import { dirname as dirname6 } from "node:path";
|
|
7410
|
+
import { homedir as homedir8 } from "node:os";
|
|
7146
7411
|
import { join as join9 } from "node:path";
|
|
7147
7412
|
var DEFAULT_BUFFER_FILE = join9(
|
|
7148
|
-
|
|
7413
|
+
homedir8(),
|
|
7149
7414
|
".cybedefend",
|
|
7150
7415
|
"guards-violations-buffer.jsonl"
|
|
7151
7416
|
);
|
|
@@ -7164,10 +7429,10 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
7164
7429
|
}
|
|
7165
7430
|
}
|
|
7166
7431
|
async function flushViolations2(ctx, postFn) {
|
|
7167
|
-
if (!
|
|
7432
|
+
if (!existsSync12(bufferFile)) return;
|
|
7168
7433
|
let content;
|
|
7169
7434
|
try {
|
|
7170
|
-
content =
|
|
7435
|
+
content = readFileSync12(bufferFile, "utf8").trim();
|
|
7171
7436
|
} catch {
|
|
7172
7437
|
return;
|
|
7173
7438
|
}
|
|
@@ -7186,7 +7451,7 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
7186
7451
|
}
|
|
7187
7452
|
if (records.length === 0) {
|
|
7188
7453
|
try {
|
|
7189
|
-
|
|
7454
|
+
writeFileSync8(bufferFile, "", "utf8");
|
|
7190
7455
|
} catch {
|
|
7191
7456
|
}
|
|
7192
7457
|
return;
|
|
@@ -7216,10 +7481,10 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
7216
7481
|
}
|
|
7217
7482
|
try {
|
|
7218
7483
|
if (failed.length === 0) {
|
|
7219
|
-
|
|
7484
|
+
writeFileSync8(bufferFile, "", "utf8");
|
|
7220
7485
|
} else {
|
|
7221
7486
|
const serialised = failed.map((r) => JSON.stringify(r)).join("\n") + "\n";
|
|
7222
|
-
|
|
7487
|
+
writeFileSync8(bufferFile, serialised, "utf8");
|
|
7223
7488
|
}
|
|
7224
7489
|
} catch {
|
|
7225
7490
|
}
|
|
@@ -7227,9 +7492,9 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
7227
7492
|
return { bufferViolation: bufferViolation2, flushViolations: flushViolations2 };
|
|
7228
7493
|
}
|
|
7229
7494
|
function ensureDirFor4(filePath) {
|
|
7230
|
-
const dir =
|
|
7231
|
-
if (!
|
|
7232
|
-
|
|
7495
|
+
const dir = dirname6(filePath);
|
|
7496
|
+
if (!existsSync12(dir)) {
|
|
7497
|
+
mkdirSync7(dir, { recursive: true });
|
|
7233
7498
|
}
|
|
7234
7499
|
}
|
|
7235
7500
|
var _defaultBuffer = makeViolationsBuffer();
|
|
@@ -7239,7 +7504,7 @@ var flushViolations = _defaultBuffer.flushViolations.bind(_defaultBuffer);
|
|
|
7239
7504
|
// src/hooks/runtime/guard-check.ts
|
|
7240
7505
|
function normalizeToolName(tool) {
|
|
7241
7506
|
if (!tool) return "";
|
|
7242
|
-
const t = tool.trim();
|
|
7507
|
+
const t = (tool.split(/[\r\n]/, 1)[0] ?? "").trim();
|
|
7243
7508
|
if (/^(read|read_file|cat)$/i.test(t)) return "Read";
|
|
7244
7509
|
if (/^(write|create_file|new_file)$/i.test(t)) return "Write";
|
|
7245
7510
|
if (/^(edit|apply_patch|str_replace_editor)$/i.test(t)) return "Edit";
|
|
@@ -7255,10 +7520,10 @@ function appendDebugLog(entry) {
|
|
|
7255
7520
|
try {
|
|
7256
7521
|
const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
7257
7522
|
if (!homeDir) return;
|
|
7258
|
-
const { mkdirSync:
|
|
7523
|
+
const { mkdirSync: mkdirSync8, appendFileSync: appendFileSync2 } = __require("node:fs");
|
|
7259
7524
|
const { join: join11 } = __require("node:path");
|
|
7260
7525
|
const dir = join11(homeDir, ".cybedefend");
|
|
7261
|
-
|
|
7526
|
+
mkdirSync8(dir, { recursive: true });
|
|
7262
7527
|
appendFileSync2(join11(dir, "hook-debug.log"), entry + "\n", "utf8");
|
|
7263
7528
|
} catch {
|
|
7264
7529
|
}
|
|
@@ -7448,6 +7713,14 @@ async function runJudgeStep(args) {
|
|
|
7448
7713
|
if (decision.maxSeverity === "critical") return void 0;
|
|
7449
7714
|
if (llmJudgeHint?.enabled === false) return void 0;
|
|
7450
7715
|
const targetStr = stringifyTarget(request.target);
|
|
7716
|
+
const injectionSurface = [
|
|
7717
|
+
targetStr,
|
|
7718
|
+
request.tool,
|
|
7719
|
+
...llmRules.flatMap((r) => [r.name ?? "", r.description ?? ""])
|
|
7720
|
+
].join("\n");
|
|
7721
|
+
if (detectPromptInjection(injectionSurface)) {
|
|
7722
|
+
return { engine: "llm", outcome: "injection_blocked" };
|
|
7723
|
+
}
|
|
7451
7724
|
const actionHash = hashTarget(targetStr);
|
|
7452
7725
|
const ruleIds = llmRules.map((r) => r.id).sort().join(",");
|
|
7453
7726
|
const cacheKey = `${actionHash}|${ruleIds}|confirm`;
|
|
@@ -7716,7 +7989,7 @@ function emitAgentMessage(verdict, message) {
|
|
|
7716
7989
|
}
|
|
7717
7990
|
function makeProductionJudgeDeps() {
|
|
7718
7991
|
const cache = makeJudgeCache();
|
|
7719
|
-
const warnDir = process.env.CYBEDEFEND_BASELINE_DIR ?? join10(
|
|
7992
|
+
const warnDir = process.env.CYBEDEFEND_BASELINE_DIR ?? join10(homedir9(), ".cybedefend");
|
|
7720
7993
|
const warnTracker = defaultSessionTracker(
|
|
7721
7994
|
join10(warnDir, "guards-judge-warned-sessions.json")
|
|
7722
7995
|
);
|
|
@@ -7740,7 +8013,7 @@ async function runPreToolUseGuard() {
|
|
|
7740
8013
|
const envelope = await readStdinJson();
|
|
7741
8014
|
const config = loadRuntimeConfig();
|
|
7742
8015
|
if (!config) return 0;
|
|
7743
|
-
const { projectId, apiBase: configApiBase } =
|
|
8016
|
+
const { projectId, apiBase: configApiBase } = await resolveProjectIdWithApi();
|
|
7744
8017
|
if (!projectId) return 0;
|
|
7745
8018
|
const apiBaseResolved = process.env.CYBEDEFEND_API_BASE ?? configApiBase ?? config.region.apiBase;
|
|
7746
8019
|
const token = await resolveTokenWithRefresh(config.region.mcpName);
|