@cybedefend/vibedefend 1.3.2 → 1.4.1
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/dist/api/projects.js +158 -0
- package/dist/api/projects.js.map +1 -0
- package/dist/clients/claude-code.js +16 -1
- package/dist/clients/claude-code.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 +548 -277
- 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/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-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.1" : 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
|
}
|
|
@@ -5924,19 +6150,19 @@ async function preCompactHook(deps = {}) {
|
|
|
5924
6150
|
}
|
|
5925
6151
|
|
|
5926
6152
|
// src/hooks/runtime/user-prompt-submit.ts
|
|
5927
|
-
import { existsSync as
|
|
5928
|
-
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";
|
|
5929
6155
|
import { join as join6 } from "node:path";
|
|
5930
6156
|
var SESSIONS_CAP = 100;
|
|
5931
6157
|
function defaultSessionsFile() {
|
|
5932
|
-
const dir = process.env.CYBEDEFEND_BASELINE_DIR ?? join6(
|
|
6158
|
+
const dir = process.env.CYBEDEFEND_BASELINE_DIR ?? join6(homedir5(), ".cybedefend");
|
|
5933
6159
|
return join6(dir, "user-prompt-seen-sessions.json");
|
|
5934
6160
|
}
|
|
5935
6161
|
function defaultSessionTracker(file = defaultSessionsFile()) {
|
|
5936
6162
|
function load() {
|
|
5937
|
-
if (!
|
|
6163
|
+
if (!existsSync9(file)) return [];
|
|
5938
6164
|
try {
|
|
5939
|
-
const raw =
|
|
6165
|
+
const raw = readFileSync9(file, "utf8");
|
|
5940
6166
|
const data = JSON.parse(raw);
|
|
5941
6167
|
if (!Array.isArray(data.sessions)) return [];
|
|
5942
6168
|
return data.sessions.filter((s) => typeof s === "string");
|
|
@@ -5953,8 +6179,8 @@ function defaultSessionTracker(file = defaultSessionsFile()) {
|
|
|
5953
6179
|
if (existing.includes(sessionId)) return;
|
|
5954
6180
|
const next = [...existing, sessionId].slice(-SESSIONS_CAP);
|
|
5955
6181
|
try {
|
|
5956
|
-
|
|
5957
|
-
|
|
6182
|
+
mkdirSync4(join6(file, ".."), { recursive: true });
|
|
6183
|
+
writeFileSync5(file, JSON.stringify({ sessions: next }), "utf8");
|
|
5958
6184
|
} catch {
|
|
5959
6185
|
}
|
|
5960
6186
|
}
|
|
@@ -5963,7 +6189,7 @@ function defaultSessionTracker(file = defaultSessionsFile()) {
|
|
|
5963
6189
|
async function userPromptSubmitHook(deps = {}) {
|
|
5964
6190
|
const readStdin = deps.readStdin ?? readStdinJson;
|
|
5965
6191
|
const loadConfig = deps.loadConfig ?? loadRuntimeConfig;
|
|
5966
|
-
const resolveProject = deps.resolveProject ??
|
|
6192
|
+
const resolveProject = deps.resolveProject ?? resolveProjectIdWithApi;
|
|
5967
6193
|
const resolveTok = deps.resolveTokenFn ?? resolveToken;
|
|
5968
6194
|
const fetchProposals = deps.fetchProposalsFn ?? fetchProposalsCount;
|
|
5969
6195
|
const emitFn = deps.emitFn ?? emit;
|
|
@@ -5976,7 +6202,7 @@ async function userPromptSubmitHook(deps = {}) {
|
|
|
5976
6202
|
}
|
|
5977
6203
|
const config = loadConfig();
|
|
5978
6204
|
if (!config) return;
|
|
5979
|
-
const { projectId, apiBase: configApiBase } = resolveProject();
|
|
6205
|
+
const { projectId, apiBase: configApiBase } = await resolveProject();
|
|
5980
6206
|
if (!projectId) return;
|
|
5981
6207
|
const apiBase = process.env.CYBEDEFEND_API_BASE ?? configApiBase ?? config.region.apiBase;
|
|
5982
6208
|
const token = resolveTok(config.region.mcpName);
|
|
@@ -6873,12 +7099,12 @@ function nearMiss(req, rule) {
|
|
|
6873
7099
|
}
|
|
6874
7100
|
|
|
6875
7101
|
// src/hooks/runtime/guard-rules-cache.ts
|
|
6876
|
-
import { readFileSync as
|
|
6877
|
-
import { dirname as
|
|
6878
|
-
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";
|
|
6879
7105
|
import { join as join7 } from "node:path";
|
|
6880
7106
|
var DEFAULT_CACHE_FILE = join7(
|
|
6881
|
-
|
|
7107
|
+
homedir6(),
|
|
6882
7108
|
".cybedefend",
|
|
6883
7109
|
"guards-cache.json"
|
|
6884
7110
|
);
|
|
@@ -6976,9 +7202,9 @@ function makeGuardRulesCache(opts) {
|
|
|
6976
7202
|
}
|
|
6977
7203
|
}
|
|
6978
7204
|
function readCache(projectId) {
|
|
6979
|
-
if (!
|
|
7205
|
+
if (!existsSync10(cacheFile)) return null;
|
|
6980
7206
|
try {
|
|
6981
|
-
const raw =
|
|
7207
|
+
const raw = readFileSync10(cacheFile, "utf8");
|
|
6982
7208
|
const data = JSON.parse(raw);
|
|
6983
7209
|
if (data.projectId !== projectId) return null;
|
|
6984
7210
|
return data;
|
|
@@ -6989,16 +7215,16 @@ function makeGuardRulesCache(opts) {
|
|
|
6989
7215
|
function writeCache(entry) {
|
|
6990
7216
|
try {
|
|
6991
7217
|
ensureDirFor2(cacheFile);
|
|
6992
|
-
|
|
7218
|
+
writeFileSync6(cacheFile, JSON.stringify(entry), "utf8");
|
|
6993
7219
|
} catch {
|
|
6994
7220
|
}
|
|
6995
7221
|
}
|
|
6996
7222
|
return { refreshIfStale };
|
|
6997
7223
|
}
|
|
6998
7224
|
function ensureDirFor2(filePath) {
|
|
6999
|
-
const dir =
|
|
7000
|
-
if (!
|
|
7001
|
-
|
|
7225
|
+
const dir = dirname4(filePath);
|
|
7226
|
+
if (!existsSync10(dir)) {
|
|
7227
|
+
mkdirSync5(dir, { recursive: true });
|
|
7002
7228
|
}
|
|
7003
7229
|
}
|
|
7004
7230
|
var DEFAULT_TIMEOUT_MS2 = 8e3;
|
|
@@ -7081,12 +7307,49 @@ async function callJudge(input, opts = {}) {
|
|
|
7081
7307
|
}
|
|
7082
7308
|
}
|
|
7083
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
|
+
|
|
7084
7347
|
// src/hooks/runtime/judge-cache.ts
|
|
7085
|
-
import { readFileSync as
|
|
7086
|
-
import { dirname as
|
|
7087
|
-
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";
|
|
7088
7351
|
var DEFAULT_JUDGE_CACHE_FILE = join8(
|
|
7089
|
-
|
|
7352
|
+
homedir7(),
|
|
7090
7353
|
".cybedefend",
|
|
7091
7354
|
"guards-judge-cache.json"
|
|
7092
7355
|
);
|
|
@@ -7096,9 +7359,9 @@ function makeJudgeCache(opts = {}) {
|
|
|
7096
7359
|
const ttlMs = opts.ttlMs ?? DEFAULT_JUDGE_TTL_MS;
|
|
7097
7360
|
const now = opts.now ?? (() => Date.now());
|
|
7098
7361
|
function readAll() {
|
|
7099
|
-
if (!
|
|
7362
|
+
if (!existsSync11(cacheFile)) return {};
|
|
7100
7363
|
try {
|
|
7101
|
-
return JSON.parse(
|
|
7364
|
+
return JSON.parse(readFileSync11(cacheFile, "utf8"));
|
|
7102
7365
|
} catch {
|
|
7103
7366
|
return {};
|
|
7104
7367
|
}
|
|
@@ -7118,36 +7381,36 @@ function makeJudgeCache(opts = {}) {
|
|
|
7118
7381
|
}
|
|
7119
7382
|
all[key] = { res, at: t };
|
|
7120
7383
|
ensureDirFor3(cacheFile);
|
|
7121
|
-
|
|
7384
|
+
writeFileSync7(cacheFile, JSON.stringify(all), "utf8");
|
|
7122
7385
|
} catch {
|
|
7123
7386
|
}
|
|
7124
7387
|
}
|
|
7125
7388
|
return { get, set };
|
|
7126
7389
|
}
|
|
7127
7390
|
function ensureDirFor3(filePath) {
|
|
7128
|
-
const dir =
|
|
7129
|
-
if (!
|
|
7130
|
-
|
|
7391
|
+
const dir = dirname5(filePath);
|
|
7392
|
+
if (!existsSync11(dir)) {
|
|
7393
|
+
mkdirSync6(dir, { recursive: true });
|
|
7131
7394
|
}
|
|
7132
7395
|
}
|
|
7133
7396
|
|
|
7134
7397
|
// src/hooks/runtime/guard-check.ts
|
|
7135
|
-
import { homedir as
|
|
7398
|
+
import { homedir as homedir9 } from "node:os";
|
|
7136
7399
|
import { join as join10 } from "node:path";
|
|
7137
7400
|
|
|
7138
7401
|
// src/hooks/runtime/guard-violations-buffer.ts
|
|
7139
7402
|
import {
|
|
7140
7403
|
appendFileSync,
|
|
7141
|
-
existsSync as
|
|
7142
|
-
readFileSync as
|
|
7143
|
-
writeFileSync as
|
|
7144
|
-
mkdirSync as
|
|
7404
|
+
existsSync as existsSync12,
|
|
7405
|
+
readFileSync as readFileSync12,
|
|
7406
|
+
writeFileSync as writeFileSync8,
|
|
7407
|
+
mkdirSync as mkdirSync7
|
|
7145
7408
|
} from "node:fs";
|
|
7146
|
-
import { dirname as
|
|
7147
|
-
import { homedir as
|
|
7409
|
+
import { dirname as dirname6 } from "node:path";
|
|
7410
|
+
import { homedir as homedir8 } from "node:os";
|
|
7148
7411
|
import { join as join9 } from "node:path";
|
|
7149
7412
|
var DEFAULT_BUFFER_FILE = join9(
|
|
7150
|
-
|
|
7413
|
+
homedir8(),
|
|
7151
7414
|
".cybedefend",
|
|
7152
7415
|
"guards-violations-buffer.jsonl"
|
|
7153
7416
|
);
|
|
@@ -7166,10 +7429,10 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
7166
7429
|
}
|
|
7167
7430
|
}
|
|
7168
7431
|
async function flushViolations2(ctx, postFn) {
|
|
7169
|
-
if (!
|
|
7432
|
+
if (!existsSync12(bufferFile)) return;
|
|
7170
7433
|
let content;
|
|
7171
7434
|
try {
|
|
7172
|
-
content =
|
|
7435
|
+
content = readFileSync12(bufferFile, "utf8").trim();
|
|
7173
7436
|
} catch {
|
|
7174
7437
|
return;
|
|
7175
7438
|
}
|
|
@@ -7188,7 +7451,7 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
7188
7451
|
}
|
|
7189
7452
|
if (records.length === 0) {
|
|
7190
7453
|
try {
|
|
7191
|
-
|
|
7454
|
+
writeFileSync8(bufferFile, "", "utf8");
|
|
7192
7455
|
} catch {
|
|
7193
7456
|
}
|
|
7194
7457
|
return;
|
|
@@ -7218,10 +7481,10 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
7218
7481
|
}
|
|
7219
7482
|
try {
|
|
7220
7483
|
if (failed.length === 0) {
|
|
7221
|
-
|
|
7484
|
+
writeFileSync8(bufferFile, "", "utf8");
|
|
7222
7485
|
} else {
|
|
7223
7486
|
const serialised = failed.map((r) => JSON.stringify(r)).join("\n") + "\n";
|
|
7224
|
-
|
|
7487
|
+
writeFileSync8(bufferFile, serialised, "utf8");
|
|
7225
7488
|
}
|
|
7226
7489
|
} catch {
|
|
7227
7490
|
}
|
|
@@ -7229,9 +7492,9 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
7229
7492
|
return { bufferViolation: bufferViolation2, flushViolations: flushViolations2 };
|
|
7230
7493
|
}
|
|
7231
7494
|
function ensureDirFor4(filePath) {
|
|
7232
|
-
const dir =
|
|
7233
|
-
if (!
|
|
7234
|
-
|
|
7495
|
+
const dir = dirname6(filePath);
|
|
7496
|
+
if (!existsSync12(dir)) {
|
|
7497
|
+
mkdirSync7(dir, { recursive: true });
|
|
7235
7498
|
}
|
|
7236
7499
|
}
|
|
7237
7500
|
var _defaultBuffer = makeViolationsBuffer();
|
|
@@ -7241,7 +7504,7 @@ var flushViolations = _defaultBuffer.flushViolations.bind(_defaultBuffer);
|
|
|
7241
7504
|
// src/hooks/runtime/guard-check.ts
|
|
7242
7505
|
function normalizeToolName(tool) {
|
|
7243
7506
|
if (!tool) return "";
|
|
7244
|
-
const t = tool.trim();
|
|
7507
|
+
const t = (tool.split(/[\r\n]/, 1)[0] ?? "").trim();
|
|
7245
7508
|
if (/^(read|read_file|cat)$/i.test(t)) return "Read";
|
|
7246
7509
|
if (/^(write|create_file|new_file)$/i.test(t)) return "Write";
|
|
7247
7510
|
if (/^(edit|apply_patch|str_replace_editor)$/i.test(t)) return "Edit";
|
|
@@ -7257,10 +7520,10 @@ function appendDebugLog(entry) {
|
|
|
7257
7520
|
try {
|
|
7258
7521
|
const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
7259
7522
|
if (!homeDir) return;
|
|
7260
|
-
const { mkdirSync:
|
|
7523
|
+
const { mkdirSync: mkdirSync8, appendFileSync: appendFileSync2 } = __require("node:fs");
|
|
7261
7524
|
const { join: join11 } = __require("node:path");
|
|
7262
7525
|
const dir = join11(homeDir, ".cybedefend");
|
|
7263
|
-
|
|
7526
|
+
mkdirSync8(dir, { recursive: true });
|
|
7264
7527
|
appendFileSync2(join11(dir, "hook-debug.log"), entry + "\n", "utf8");
|
|
7265
7528
|
} catch {
|
|
7266
7529
|
}
|
|
@@ -7450,6 +7713,14 @@ async function runJudgeStep(args) {
|
|
|
7450
7713
|
if (decision.maxSeverity === "critical") return void 0;
|
|
7451
7714
|
if (llmJudgeHint?.enabled === false) return void 0;
|
|
7452
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
|
+
}
|
|
7453
7724
|
const actionHash = hashTarget(targetStr);
|
|
7454
7725
|
const ruleIds = llmRules.map((r) => r.id).sort().join(",");
|
|
7455
7726
|
const cacheKey = `${actionHash}|${ruleIds}|confirm`;
|
|
@@ -7718,7 +7989,7 @@ function emitAgentMessage(verdict, message) {
|
|
|
7718
7989
|
}
|
|
7719
7990
|
function makeProductionJudgeDeps() {
|
|
7720
7991
|
const cache = makeJudgeCache();
|
|
7721
|
-
const warnDir = process.env.CYBEDEFEND_BASELINE_DIR ?? join10(
|
|
7992
|
+
const warnDir = process.env.CYBEDEFEND_BASELINE_DIR ?? join10(homedir9(), ".cybedefend");
|
|
7722
7993
|
const warnTracker = defaultSessionTracker(
|
|
7723
7994
|
join10(warnDir, "guards-judge-warned-sessions.json")
|
|
7724
7995
|
);
|
|
@@ -7742,7 +8013,7 @@ async function runPreToolUseGuard() {
|
|
|
7742
8013
|
const envelope = await readStdinJson();
|
|
7743
8014
|
const config = loadRuntimeConfig();
|
|
7744
8015
|
if (!config) return 0;
|
|
7745
|
-
const { projectId, apiBase: configApiBase } =
|
|
8016
|
+
const { projectId, apiBase: configApiBase } = await resolveProjectIdWithApi();
|
|
7746
8017
|
if (!projectId) return 0;
|
|
7747
8018
|
const apiBaseResolved = process.env.CYBEDEFEND_API_BASE ?? configApiBase ?? config.region.apiBase;
|
|
7748
8019
|
const token = await resolveTokenWithRefresh(config.region.mcpName);
|