coderifts 1.8.4 → 2.0.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 +42 -0
- package/bin/coderifts.js +44 -1
- package/dist/cli.js +4292 -48
- package/package.json +6 -3
- package/scripts/assert-publish-gate.sh +42 -0
package/dist/cli.js
CHANGED
|
@@ -3007,7 +3007,7 @@ var require_package = __commonJS({
|
|
|
3007
3007
|
"package.json"(exports2, module2) {
|
|
3008
3008
|
module2.exports = {
|
|
3009
3009
|
name: "coderifts",
|
|
3010
|
-
version: "
|
|
3010
|
+
version: "2.0.0",
|
|
3011
3011
|
description: "Detect breaking API changes from the command line. Works locally or with the CodeRifts cloud API.",
|
|
3012
3012
|
author: "CodeRifts <hello@coderifts.com>",
|
|
3013
3013
|
license: "MIT",
|
|
@@ -3050,11 +3050,12 @@ var require_package = __commonJS({
|
|
|
3050
3050
|
test: "node --test test/*.test.js"
|
|
3051
3051
|
},
|
|
3052
3052
|
dependencies: {
|
|
3053
|
+
"@coderifts/agent-guard": "^1.6.0",
|
|
3053
3054
|
chalk: "^4.1.2",
|
|
3054
3055
|
"cli-table3": "^0.6.4",
|
|
3055
3056
|
commander: "^12.0.0",
|
|
3056
3057
|
inquirer: "^8.2.6",
|
|
3057
|
-
"js-yaml": "^4.
|
|
3058
|
+
"js-yaml": "^4.3.1",
|
|
3058
3059
|
"openapi-diff": "^0.24.1",
|
|
3059
3060
|
ora: "^5.4.1"
|
|
3060
3061
|
},
|
|
@@ -3062,7 +3063,9 @@ var require_package = __commonJS({
|
|
|
3062
3063
|
"z-schema": "^7.2.0",
|
|
3063
3064
|
"json-schema-ref-parser": "npm:@apidevtools/json-schema-ref-parser@^11.7.3",
|
|
3064
3065
|
"form-data": "^4.0.6",
|
|
3065
|
-
axios: ">=1.18.0"
|
|
3066
|
+
axios: ">=1.18.0",
|
|
3067
|
+
"fast-uri": ">=3.1.5",
|
|
3068
|
+
"brace-expansion": "5.0.9"
|
|
3066
3069
|
},
|
|
3067
3070
|
devDependencies: {
|
|
3068
3071
|
esbuild: "^0.28.1"
|
|
@@ -4366,7 +4369,7 @@ var require_templates = __commonJS({
|
|
|
4366
4369
|
if (!Number.isNaN(number)) {
|
|
4367
4370
|
results.push(number);
|
|
4368
4371
|
} else if (matches = chunk.match(STRING_REGEX)) {
|
|
4369
|
-
results.push(matches[2].replace(ESCAPE_REGEX, (m,
|
|
4372
|
+
results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape2(escape) : character));
|
|
4370
4373
|
} else {
|
|
4371
4374
|
throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
|
|
4372
4375
|
}
|
|
@@ -11255,7 +11258,7 @@ var require_omap = __commonJS({
|
|
|
11255
11258
|
var _toString = Object.prototype.toString;
|
|
11256
11259
|
function resolveYamlOmap(data) {
|
|
11257
11260
|
if (data === null) return true;
|
|
11258
|
-
const objectKeys =
|
|
11261
|
+
const objectKeys = {};
|
|
11259
11262
|
const object = data;
|
|
11260
11263
|
for (let index = 0, length = object.length; index < length; index += 1) {
|
|
11261
11264
|
const pair = object[index];
|
|
@@ -11269,8 +11272,8 @@ var require_omap = __commonJS({
|
|
|
11269
11272
|
}
|
|
11270
11273
|
}
|
|
11271
11274
|
if (!pairHasKey) return false;
|
|
11272
|
-
if (
|
|
11273
|
-
|
|
11275
|
+
if (_hasOwnProperty.call(objectKeys, pairKey)) return false;
|
|
11276
|
+
Object.defineProperty(objectKeys, pairKey, { value: true });
|
|
11274
11277
|
}
|
|
11275
11278
|
return true;
|
|
11276
11279
|
}
|
|
@@ -24777,7 +24780,7 @@ var require_lodash = __commonJS({
|
|
|
24777
24780
|
position -= target.length;
|
|
24778
24781
|
return position >= 0 && string.slice(position, end) == target;
|
|
24779
24782
|
}
|
|
24780
|
-
function
|
|
24783
|
+
function escape(string) {
|
|
24781
24784
|
string = toString(string);
|
|
24782
24785
|
return string && reHasUnescapedHtml.test(string) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string;
|
|
24783
24786
|
}
|
|
@@ -25388,7 +25391,7 @@ var require_lodash = __commonJS({
|
|
|
25388
25391
|
lodash.divide = divide;
|
|
25389
25392
|
lodash.endsWith = endsWith;
|
|
25390
25393
|
lodash.eq = eq;
|
|
25391
|
-
lodash.escape =
|
|
25394
|
+
lodash.escape = escape;
|
|
25392
25395
|
lodash.escapeRegExp = escapeRegExp;
|
|
25393
25396
|
lodash.every = every;
|
|
25394
25397
|
lodash.find = find;
|
|
@@ -29362,6 +29365,7 @@ var require_utils2 = __commonJS({
|
|
|
29362
29365
|
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
29363
29366
|
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
29364
29367
|
var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
|
|
29368
|
+
var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/?]$/iu);
|
|
29365
29369
|
function stringArrayToHexStripped(input) {
|
|
29366
29370
|
let acc = "";
|
|
29367
29371
|
let code = 0;
|
|
@@ -29504,7 +29508,7 @@ var require_utils2 = __commonJS({
|
|
|
29504
29508
|
continue;
|
|
29505
29509
|
}
|
|
29506
29510
|
} else if (input[0] === "/") {
|
|
29507
|
-
if (input[1] === "."
|
|
29511
|
+
if (input[1] === ".") {
|
|
29508
29512
|
output.push("/");
|
|
29509
29513
|
break;
|
|
29510
29514
|
}
|
|
@@ -29586,10 +29590,30 @@ var require_utils2 = __commonJS({
|
|
|
29586
29590
|
}
|
|
29587
29591
|
return output;
|
|
29588
29592
|
}
|
|
29593
|
+
var BYTE_HEX = new Array(256);
|
|
29594
|
+
{
|
|
29595
|
+
const HEX_DIGITS = "0123456789ABCDEF";
|
|
29596
|
+
for (let i = 0; i < 256; i++) {
|
|
29597
|
+
BYTE_HEX[i] = "%" + HEX_DIGITS[i >> 4] + HEX_DIGITS[i & 15];
|
|
29598
|
+
}
|
|
29599
|
+
}
|
|
29600
|
+
function isEscapeSafe(cp) {
|
|
29601
|
+
return cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp === 42 || cp === 43 || cp === 45 || cp === 46 || cp === 47 || cp === 64 || cp === 95;
|
|
29602
|
+
}
|
|
29603
|
+
function percentEncodeNonAscii(cp) {
|
|
29604
|
+
if (cp < 2048) {
|
|
29605
|
+
return BYTE_HEX[192 | cp >> 6] + BYTE_HEX[128 | cp & 63];
|
|
29606
|
+
}
|
|
29607
|
+
if (cp < 65536) {
|
|
29608
|
+
return BYTE_HEX[224 | cp >> 12] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
29609
|
+
}
|
|
29610
|
+
return BYTE_HEX[240 | cp >> 18] + BYTE_HEX[128 | cp >> 12 & 63] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
29611
|
+
}
|
|
29589
29612
|
function normalizePathEncoding(input) {
|
|
29590
29613
|
let output = "";
|
|
29591
29614
|
for (let i = 0; i < input.length; i++) {
|
|
29592
|
-
|
|
29615
|
+
const ch = input[i];
|
|
29616
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
29593
29617
|
const hex = input.slice(i + 1, i + 3);
|
|
29594
29618
|
if (isHexPair(hex)) {
|
|
29595
29619
|
const normalizedHex = hex.toUpperCase();
|
|
@@ -29603,10 +29627,66 @@ var require_utils2 = __commonJS({
|
|
|
29603
29627
|
continue;
|
|
29604
29628
|
}
|
|
29605
29629
|
}
|
|
29606
|
-
if (isPathCharacter(
|
|
29607
|
-
output +=
|
|
29630
|
+
if (isPathCharacter(ch)) {
|
|
29631
|
+
output += ch;
|
|
29608
29632
|
} else {
|
|
29609
|
-
|
|
29633
|
+
const code = input.charCodeAt(i);
|
|
29634
|
+
if (code < 128) {
|
|
29635
|
+
output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
|
|
29636
|
+
} else if (code < 55296 || code > 57343) {
|
|
29637
|
+
output += percentEncodeNonAscii(code);
|
|
29638
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
29639
|
+
const low = input.charCodeAt(i + 1);
|
|
29640
|
+
if (low >= 56320 && low <= 57343) {
|
|
29641
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
29642
|
+
i++;
|
|
29643
|
+
} else {
|
|
29644
|
+
output += percentEncodeNonAscii(65533);
|
|
29645
|
+
}
|
|
29646
|
+
} else {
|
|
29647
|
+
output += percentEncodeNonAscii(65533);
|
|
29648
|
+
}
|
|
29649
|
+
}
|
|
29650
|
+
}
|
|
29651
|
+
return output;
|
|
29652
|
+
}
|
|
29653
|
+
function normalizeQueryFragmentEncoding(input) {
|
|
29654
|
+
let output = "";
|
|
29655
|
+
for (let i = 0; i < input.length; i++) {
|
|
29656
|
+
const ch = input[i];
|
|
29657
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
29658
|
+
const hex = input.slice(i + 1, i + 3);
|
|
29659
|
+
if (isHexPair(hex)) {
|
|
29660
|
+
const normalizedHex = hex.toUpperCase();
|
|
29661
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
29662
|
+
if (isUnreserved(decoded)) {
|
|
29663
|
+
output += decoded;
|
|
29664
|
+
} else {
|
|
29665
|
+
output += "%" + normalizedHex;
|
|
29666
|
+
}
|
|
29667
|
+
i += 2;
|
|
29668
|
+
continue;
|
|
29669
|
+
}
|
|
29670
|
+
}
|
|
29671
|
+
if (isQueryFragmentCharacter(ch)) {
|
|
29672
|
+
output += ch;
|
|
29673
|
+
} else {
|
|
29674
|
+
const code = input.charCodeAt(i);
|
|
29675
|
+
if (code < 128) {
|
|
29676
|
+
output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
|
|
29677
|
+
} else if (code < 55296 || code > 57343) {
|
|
29678
|
+
output += percentEncodeNonAscii(code);
|
|
29679
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
29680
|
+
const low = input.charCodeAt(i + 1);
|
|
29681
|
+
if (low >= 56320 && low <= 57343) {
|
|
29682
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
29683
|
+
i++;
|
|
29684
|
+
} else {
|
|
29685
|
+
output += percentEncodeNonAscii(65533);
|
|
29686
|
+
}
|
|
29687
|
+
} else {
|
|
29688
|
+
output += percentEncodeNonAscii(65533);
|
|
29689
|
+
}
|
|
29610
29690
|
}
|
|
29611
29691
|
}
|
|
29612
29692
|
return output;
|
|
@@ -29614,7 +29694,8 @@ var require_utils2 = __commonJS({
|
|
|
29614
29694
|
function escapePreservingEscapes(input) {
|
|
29615
29695
|
let output = "";
|
|
29616
29696
|
for (let i = 0; i < input.length; i++) {
|
|
29617
|
-
|
|
29697
|
+
const ch = input[i];
|
|
29698
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
29618
29699
|
const hex = input.slice(i + 1, i + 3);
|
|
29619
29700
|
if (isHexPair(hex)) {
|
|
29620
29701
|
output += "%" + hex.toUpperCase();
|
|
@@ -29622,7 +29703,22 @@ var require_utils2 = __commonJS({
|
|
|
29622
29703
|
continue;
|
|
29623
29704
|
}
|
|
29624
29705
|
}
|
|
29625
|
-
|
|
29706
|
+
const code = input.charCodeAt(i);
|
|
29707
|
+
if (code < 128) {
|
|
29708
|
+
output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
|
|
29709
|
+
} else if (code < 55296 || code > 57343) {
|
|
29710
|
+
output += percentEncodeNonAscii(code);
|
|
29711
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
29712
|
+
const low = input.charCodeAt(i + 1);
|
|
29713
|
+
if (low >= 56320 && low <= 57343) {
|
|
29714
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
29715
|
+
i++;
|
|
29716
|
+
} else {
|
|
29717
|
+
output += percentEncodeNonAscii(65533);
|
|
29718
|
+
}
|
|
29719
|
+
} else {
|
|
29720
|
+
output += percentEncodeNonAscii(65533);
|
|
29721
|
+
}
|
|
29626
29722
|
}
|
|
29627
29723
|
return output;
|
|
29628
29724
|
}
|
|
@@ -29656,6 +29752,7 @@ var require_utils2 = __commonJS({
|
|
|
29656
29752
|
reescapeHostDelimiters,
|
|
29657
29753
|
normalizePercentEncoding,
|
|
29658
29754
|
normalizePathEncoding,
|
|
29755
|
+
normalizeQueryFragmentEncoding,
|
|
29659
29756
|
escapePreservingEscapes,
|
|
29660
29757
|
removeDotSegments,
|
|
29661
29758
|
isIPv4,
|
|
@@ -29880,7 +29977,7 @@ var require_schemes = __commonJS({
|
|
|
29880
29977
|
var require_fast_uri = __commonJS({
|
|
29881
29978
|
"node_modules/fast-uri/index.js"(exports2, module2) {
|
|
29882
29979
|
"use strict";
|
|
29883
|
-
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils2();
|
|
29980
|
+
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, normalizeQueryFragmentEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils2();
|
|
29884
29981
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
29885
29982
|
function normalize(uri, options) {
|
|
29886
29983
|
if (typeof uri === "string") {
|
|
@@ -29894,7 +29991,12 @@ var require_fast_uri = __commonJS({
|
|
|
29894
29991
|
}
|
|
29895
29992
|
function resolve(baseURI, relativeURI, options) {
|
|
29896
29993
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
29897
|
-
const
|
|
29994
|
+
const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
|
|
29995
|
+
const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
|
|
29996
|
+
if (baseMalformed || relativeMalformed) {
|
|
29997
|
+
throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
|
|
29998
|
+
}
|
|
29999
|
+
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
|
|
29898
30000
|
schemelessOptions.skipEscape = true;
|
|
29899
30001
|
return serialize(resolved, schemelessOptions);
|
|
29900
30002
|
}
|
|
@@ -30020,6 +30122,7 @@ var require_fast_uri = __commonJS({
|
|
|
30020
30122
|
}
|
|
30021
30123
|
var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
30022
30124
|
var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
|
|
30125
|
+
var AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
|
|
30023
30126
|
function getParseError(parsed, matches) {
|
|
30024
30127
|
if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
|
|
30025
30128
|
return 'URI path must start with "/" when authority is present.';
|
|
@@ -30054,9 +30157,23 @@ var require_fast_uri = __commonJS({
|
|
|
30054
30157
|
parsed.error = "URI authority must not contain a literal backslash.";
|
|
30055
30158
|
malformedAuthorityOrPort = true;
|
|
30056
30159
|
}
|
|
30160
|
+
const introducerMatch = uri.match(AUTHORITY_INTRODUCER_REGION);
|
|
30161
|
+
if (introducerMatch !== null) {
|
|
30162
|
+
const region = introducerMatch[1];
|
|
30163
|
+
const normalizedRegion = region.replace(/[\t\n\r]/g, "");
|
|
30164
|
+
if (normalizedRegion.length >= 2) {
|
|
30165
|
+
if (normalizedRegion.slice(0, 2) !== "//") {
|
|
30166
|
+
parsed.error = parsed.error || "URI authority must not contain a literal backslash.";
|
|
30167
|
+
malformedAuthorityOrPort = true;
|
|
30168
|
+
} else if (region.length !== normalizedRegion.length) {
|
|
30169
|
+
parsed.error = parsed.error || "URI authority introducer must not contain whitespace.";
|
|
30170
|
+
malformedAuthorityOrPort = true;
|
|
30171
|
+
}
|
|
30172
|
+
}
|
|
30173
|
+
}
|
|
30057
30174
|
const matches = uri.match(URI_PARSE);
|
|
30058
30175
|
if (matches) {
|
|
30059
|
-
parsed.scheme = matches[1];
|
|
30176
|
+
parsed.scheme = matches[1] === void 0 ? void 0 : matches[1].toLowerCase();
|
|
30060
30177
|
parsed.userinfo = matches[3];
|
|
30061
30178
|
parsed.host = matches[4];
|
|
30062
30179
|
parsed.port = parseInt(matches[5], 10);
|
|
@@ -30115,12 +30232,11 @@ var require_fast_uri = __commonJS({
|
|
|
30115
30232
|
if (parsed.path) {
|
|
30116
30233
|
parsed.path = normalizePathEncoding(parsed.path);
|
|
30117
30234
|
}
|
|
30235
|
+
if (parsed.query) {
|
|
30236
|
+
parsed.query = normalizeQueryFragmentEncoding(parsed.query);
|
|
30237
|
+
}
|
|
30118
30238
|
if (parsed.fragment) {
|
|
30119
|
-
|
|
30120
|
-
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
|
|
30121
|
-
} catch {
|
|
30122
|
-
parsed.error = parsed.error || "URI malformed";
|
|
30123
|
-
}
|
|
30239
|
+
parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
|
|
30124
30240
|
}
|
|
30125
30241
|
}
|
|
30126
30242
|
if (schemeHandler && schemeHandler.parse) {
|
|
@@ -61749,7 +61865,7 @@ var require_axios = __commonJS({
|
|
|
61749
61865
|
advertiseZstdAcceptEncoding: false,
|
|
61750
61866
|
validateStatusUndefinedResolves: true
|
|
61751
61867
|
};
|
|
61752
|
-
var
|
|
61868
|
+
var URLSearchParams2 = url.URLSearchParams;
|
|
61753
61869
|
var ALPHA = "abcdefghijklmnopqrstuvwxyz";
|
|
61754
61870
|
var DIGIT = "0123456789";
|
|
61755
61871
|
var ALPHABET = {
|
|
@@ -61772,7 +61888,7 @@ var require_axios = __commonJS({
|
|
|
61772
61888
|
var platform$1 = {
|
|
61773
61889
|
isNode: true,
|
|
61774
61890
|
classes: {
|
|
61775
|
-
URLSearchParams,
|
|
61891
|
+
URLSearchParams: URLSearchParams2,
|
|
61776
61892
|
FormData: FormData$1,
|
|
61777
61893
|
Blob: typeof Blob !== "undefined" && Blob || null
|
|
61778
61894
|
},
|
|
@@ -65405,6 +65521,3998 @@ var require_diff = __commonJS({
|
|
|
65405
65521
|
}
|
|
65406
65522
|
});
|
|
65407
65523
|
|
|
65524
|
+
// node_modules/@coderifts/sdk/dist/cjs/errors.js
|
|
65525
|
+
var require_errors5 = __commonJS({
|
|
65526
|
+
"node_modules/@coderifts/sdk/dist/cjs/errors.js"(exports2) {
|
|
65527
|
+
"use strict";
|
|
65528
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
65529
|
+
exports2.AuthError = exports2.RateLimitError = exports2.TimeoutError = exports2.ApiError = exports2.CodeRiftsError = void 0;
|
|
65530
|
+
var CodeRiftsError = class extends Error {
|
|
65531
|
+
code;
|
|
65532
|
+
constructor(message, code = "unknown") {
|
|
65533
|
+
super(message);
|
|
65534
|
+
this.name = "CodeRiftsError";
|
|
65535
|
+
this.code = code;
|
|
65536
|
+
}
|
|
65537
|
+
};
|
|
65538
|
+
exports2.CodeRiftsError = CodeRiftsError;
|
|
65539
|
+
var ApiError = class extends CodeRiftsError {
|
|
65540
|
+
status;
|
|
65541
|
+
code;
|
|
65542
|
+
body;
|
|
65543
|
+
constructor(status, body) {
|
|
65544
|
+
super(`[${status}] ${body.error}: ${body.message}`);
|
|
65545
|
+
this.name = "ApiError";
|
|
65546
|
+
this.status = status;
|
|
65547
|
+
this.code = body.error;
|
|
65548
|
+
this.body = body;
|
|
65549
|
+
}
|
|
65550
|
+
};
|
|
65551
|
+
exports2.ApiError = ApiError;
|
|
65552
|
+
var TimeoutError = class extends CodeRiftsError {
|
|
65553
|
+
constructor(timeoutMs) {
|
|
65554
|
+
super(`Request timed out after ${timeoutMs}ms`);
|
|
65555
|
+
this.name = "TimeoutError";
|
|
65556
|
+
}
|
|
65557
|
+
};
|
|
65558
|
+
exports2.TimeoutError = TimeoutError;
|
|
65559
|
+
var RateLimitError = class extends ApiError {
|
|
65560
|
+
constructor(body) {
|
|
65561
|
+
super(429, body);
|
|
65562
|
+
this.name = "RateLimitError";
|
|
65563
|
+
}
|
|
65564
|
+
};
|
|
65565
|
+
exports2.RateLimitError = RateLimitError;
|
|
65566
|
+
var AuthError = class extends ApiError {
|
|
65567
|
+
constructor(body) {
|
|
65568
|
+
super(401, body);
|
|
65569
|
+
this.name = "AuthError";
|
|
65570
|
+
}
|
|
65571
|
+
};
|
|
65572
|
+
exports2.AuthError = AuthError;
|
|
65573
|
+
}
|
|
65574
|
+
});
|
|
65575
|
+
|
|
65576
|
+
// node_modules/@coderifts/sdk/dist/cjs/client.js
|
|
65577
|
+
var require_client = __commonJS({
|
|
65578
|
+
"node_modules/@coderifts/sdk/dist/cjs/client.js"(exports2) {
|
|
65579
|
+
"use strict";
|
|
65580
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
65581
|
+
exports2.CodeRifts = void 0;
|
|
65582
|
+
var errors_js_1 = require_errors5();
|
|
65583
|
+
var DEFAULT_BASE_URL = "https://app.coderifts.com";
|
|
65584
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
65585
|
+
var CodeRifts = class {
|
|
65586
|
+
apiKey;
|
|
65587
|
+
baseUrl;
|
|
65588
|
+
timeout;
|
|
65589
|
+
constructor(options) {
|
|
65590
|
+
if (!options.apiKey) {
|
|
65591
|
+
throw new Error("apiKey is required");
|
|
65592
|
+
}
|
|
65593
|
+
this.apiKey = options.apiKey;
|
|
65594
|
+
this.baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
65595
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
65596
|
+
}
|
|
65597
|
+
// ─── Internal HTTP helper ──────────────────────────────────────────────
|
|
65598
|
+
async request(method, path, body) {
|
|
65599
|
+
const url = `${this.baseUrl}${path}`;
|
|
65600
|
+
const controller = new AbortController();
|
|
65601
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
65602
|
+
try {
|
|
65603
|
+
const res = await fetch(url, {
|
|
65604
|
+
method,
|
|
65605
|
+
headers: {
|
|
65606
|
+
"Content-Type": "application/json",
|
|
65607
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
65608
|
+
},
|
|
65609
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
65610
|
+
signal: controller.signal
|
|
65611
|
+
});
|
|
65612
|
+
const json = await res.json();
|
|
65613
|
+
if (!res.ok) {
|
|
65614
|
+
const errorBody = {
|
|
65615
|
+
error: json.error || "unknown",
|
|
65616
|
+
message: json.message || res.statusText
|
|
65617
|
+
};
|
|
65618
|
+
if (res.status === 401)
|
|
65619
|
+
throw new errors_js_1.AuthError(errorBody);
|
|
65620
|
+
if (res.status === 429)
|
|
65621
|
+
throw new errors_js_1.RateLimitError(errorBody);
|
|
65622
|
+
throw new errors_js_1.ApiError(res.status, errorBody);
|
|
65623
|
+
}
|
|
65624
|
+
return json;
|
|
65625
|
+
} catch (err) {
|
|
65626
|
+
if (err instanceof errors_js_1.ApiError)
|
|
65627
|
+
throw err;
|
|
65628
|
+
if (err.name === "AbortError") {
|
|
65629
|
+
throw new errors_js_1.TimeoutError(this.timeout);
|
|
65630
|
+
}
|
|
65631
|
+
throw err;
|
|
65632
|
+
} finally {
|
|
65633
|
+
clearTimeout(timer);
|
|
65634
|
+
}
|
|
65635
|
+
}
|
|
65636
|
+
// ─── 1. preflightCheck ─────────────────────────────────────────────────
|
|
65637
|
+
/**
|
|
65638
|
+
* Check whether it is safe to proceed with a tool invocation.
|
|
65639
|
+
*
|
|
65640
|
+
* Accepts `old_spec` / `new_spec` (OpenAPI YAML strings) and a `tool_name`.
|
|
65641
|
+
* The SDK converts the specs to MCP tool arrays and calls POST /api/v1/agent/preflight.
|
|
65642
|
+
*/
|
|
65643
|
+
async preflightCheck(req) {
|
|
65644
|
+
const raw = await this.request("POST", "/api/v1/agent/preflight", {
|
|
65645
|
+
tool_name: req.tool_name,
|
|
65646
|
+
old_spec: req.old_spec,
|
|
65647
|
+
new_spec: req.new_spec
|
|
65648
|
+
});
|
|
65649
|
+
const decision = raw.decision || "ALLOW";
|
|
65650
|
+
return {
|
|
65651
|
+
decision,
|
|
65652
|
+
omega_api: raw.omega_api ?? 0,
|
|
65653
|
+
safe: decision === "ALLOW" || decision === "WARN",
|
|
65654
|
+
reflex_triggers: raw.reflex_triggers || [],
|
|
65655
|
+
affected_tools: raw.affected_tools || [],
|
|
65656
|
+
confidence_score: raw.confidence_score,
|
|
65657
|
+
reflex_override: raw.reflex_override,
|
|
65658
|
+
omega_components: raw.omega_components,
|
|
65659
|
+
breaking_changes: raw.breaking_changes,
|
|
65660
|
+
stats: raw.stats,
|
|
65661
|
+
mitigation_available: raw.mitigation_available
|
|
65662
|
+
};
|
|
65663
|
+
}
|
|
65664
|
+
// ─── 2. diff ───────────────────────────────────────────────────────────
|
|
65665
|
+
/**
|
|
65666
|
+
* Full analysis of two OpenAPI specs.
|
|
65667
|
+
*/
|
|
65668
|
+
async diff(req) {
|
|
65669
|
+
return this.request("POST", "/api/v1/diff", req);
|
|
65670
|
+
}
|
|
65671
|
+
// ─── 3. explainDecision ────────────────────────────────────────────────
|
|
65672
|
+
/**
|
|
65673
|
+
* Returns a human-readable explanation of why a decision was made.
|
|
65674
|
+
*
|
|
65675
|
+
* Computed client-side from the omega components and reflex triggers.
|
|
65676
|
+
*/
|
|
65677
|
+
async explainDecision(req) {
|
|
65678
|
+
const components = [];
|
|
65679
|
+
if (req.omega_components) {
|
|
65680
|
+
for (const [name, value] of Object.entries(req.omega_components)) {
|
|
65681
|
+
if (typeof value === "number") {
|
|
65682
|
+
components.push({
|
|
65683
|
+
name,
|
|
65684
|
+
value,
|
|
65685
|
+
description: describeComponent(name, value)
|
|
65686
|
+
});
|
|
65687
|
+
}
|
|
65688
|
+
}
|
|
65689
|
+
}
|
|
65690
|
+
const triggers = req.reflex_triggers || [];
|
|
65691
|
+
let summary = `Decision: ${req.decision} (\u03A9_API = ${req.omega_api}).`;
|
|
65692
|
+
if (triggers.length > 0) {
|
|
65693
|
+
summary += ` ${triggers.length} reflex rule(s) triggered.`;
|
|
65694
|
+
}
|
|
65695
|
+
if (req.decision === "BLOCK") {
|
|
65696
|
+
summary += " This change is blocked due to high risk.";
|
|
65697
|
+
} else if (req.decision === "REQUIRE_APPROVAL") {
|
|
65698
|
+
summary += " This change requires manual approval before merging.";
|
|
65699
|
+
} else if (req.decision === "WARN") {
|
|
65700
|
+
summary += " This change has warnings but can proceed.";
|
|
65701
|
+
} else {
|
|
65702
|
+
summary += " This change is safe to proceed.";
|
|
65703
|
+
}
|
|
65704
|
+
return { summary, components };
|
|
65705
|
+
}
|
|
65706
|
+
// ─── 4. howToUnblock ───────────────────────────────────────────────────
|
|
65707
|
+
/**
|
|
65708
|
+
* Returns actionable steps to resolve a BLOCK decision.
|
|
65709
|
+
*
|
|
65710
|
+
* Computed client-side from breaking changes and detected patterns.
|
|
65711
|
+
*/
|
|
65712
|
+
async howToUnblock(req) {
|
|
65713
|
+
const actions = [];
|
|
65714
|
+
let step = 1;
|
|
65715
|
+
if (req.decision !== "BLOCK") {
|
|
65716
|
+
actions.push({
|
|
65717
|
+
step: step++,
|
|
65718
|
+
description: `Current decision is "${req.decision}" \u2014 no unblock needed.`
|
|
65719
|
+
});
|
|
65720
|
+
return { actions };
|
|
65721
|
+
}
|
|
65722
|
+
const bcs = req.breaking_changes || [];
|
|
65723
|
+
if (bcs.length > 0) {
|
|
65724
|
+
actions.push({
|
|
65725
|
+
step: step++,
|
|
65726
|
+
description: `Fix ${bcs.length} breaking change(s) in your spec.`,
|
|
65727
|
+
code_example: bcs.slice(0, 3).map((bc) => `# ${bc.type} at ${bc.path}: ${bc.description}`).join("\n")
|
|
65728
|
+
});
|
|
65729
|
+
}
|
|
65730
|
+
const triggers = req.reflex_triggers || [];
|
|
65731
|
+
for (const trigger of triggers) {
|
|
65732
|
+
actions.push({
|
|
65733
|
+
step: step++,
|
|
65734
|
+
description: `Resolve reflex rule: ${trigger.rule}`
|
|
65735
|
+
});
|
|
65736
|
+
}
|
|
65737
|
+
actions.push({
|
|
65738
|
+
step: step++,
|
|
65739
|
+
description: "Request a manual override via POST /api/v1/ledger/:id/override if this is an emergency."
|
|
65740
|
+
});
|
|
65741
|
+
return { actions };
|
|
65742
|
+
}
|
|
65743
|
+
// ─── 5. scoreMcp ──────────────────────────────────────────────────────
|
|
65744
|
+
/**
|
|
65745
|
+
* Score an MCP manifest for agent safety.
|
|
65746
|
+
*/
|
|
65747
|
+
async scoreMcp(req) {
|
|
65748
|
+
return this.request("POST", "/api/v1/agent-readiness-score", {
|
|
65749
|
+
spec: req.manifest,
|
|
65750
|
+
spec_type: "mcp"
|
|
65751
|
+
});
|
|
65752
|
+
}
|
|
65753
|
+
// ─── 6. getLedger ─────────────────────────────────────────────────────
|
|
65754
|
+
/**
|
|
65755
|
+
* Query compliance ledger entries.
|
|
65756
|
+
*/
|
|
65757
|
+
async getLedger(req = {}) {
|
|
65758
|
+
const params = new URLSearchParams();
|
|
65759
|
+
if (req.repo)
|
|
65760
|
+
params.set("repo", req.repo);
|
|
65761
|
+
if (req.decision)
|
|
65762
|
+
params.set("decision", req.decision);
|
|
65763
|
+
if (req.from)
|
|
65764
|
+
params.set("from", req.from);
|
|
65765
|
+
if (req.to)
|
|
65766
|
+
params.set("to", req.to);
|
|
65767
|
+
if (req.limit)
|
|
65768
|
+
params.set("limit", String(req.limit));
|
|
65769
|
+
const qs = params.toString();
|
|
65770
|
+
const path = `/api/v1/ledger${qs ? `?${qs}` : ""}`;
|
|
65771
|
+
return this.request("GET", path);
|
|
65772
|
+
}
|
|
65773
|
+
// ─── 7. simulatePolicy ───────────────────────────────────────────────
|
|
65774
|
+
/**
|
|
65775
|
+
* Test a YAML policy against two OpenAPI specs.
|
|
65776
|
+
*/
|
|
65777
|
+
async simulatePolicy(req) {
|
|
65778
|
+
return this.request("POST", "/api/v1/policy-simulator", req);
|
|
65779
|
+
}
|
|
65780
|
+
// ─── 8. preflightChangeSet ─────────────────────────────────────────────
|
|
65781
|
+
/**
|
|
65782
|
+
* Preflight a multi-artifact change set (OpenAPI / GraphQL / gRPC / AsyncAPI / MCP manifest)
|
|
65783
|
+
* in one call. Returns one aggregated ALLOW/WARN/REQUIRE_APPROVAL/BLOCK decision (strictest-wins)
|
|
65784
|
+
* with per-artifact findings, a bundle fingerprint, and a decision-result.v1.1 envelope +
|
|
65785
|
+
* chain receipt. POST /api/v1/preflight.
|
|
65786
|
+
*/
|
|
65787
|
+
async preflightChangeSet(req) {
|
|
65788
|
+
return this.request("POST", "/api/v1/preflight", req);
|
|
65789
|
+
}
|
|
65790
|
+
// ─── 9. verifyReceipt ──────────────────────────────────────────────────
|
|
65791
|
+
/**
|
|
65792
|
+
* Verify a CodeRifts chain receipt's signature and integrity. No API key is required — this is a
|
|
65793
|
+
* public endpoint (the Authorization header is sent for consistency but ignored server-side).
|
|
65794
|
+
* POST /api/v1/verify-receipt.
|
|
65795
|
+
*/
|
|
65796
|
+
async verifyReceipt(token) {
|
|
65797
|
+
return this.request("POST", "/api/v1/verify-receipt", { token });
|
|
65798
|
+
}
|
|
65799
|
+
// ─── 10. getDecisionDetails ────────────────────────────────────────────
|
|
65800
|
+
/**
|
|
65801
|
+
* Look up a stored decision by decision_id or fingerprint; returns the stored
|
|
65802
|
+
* decision-result.v1.1 envelope + meta. POST /api/v1/decisions/lookup.
|
|
65803
|
+
*/
|
|
65804
|
+
async getDecisionDetails(req) {
|
|
65805
|
+
return this.request("POST", "/api/v1/decisions/lookup", req);
|
|
65806
|
+
}
|
|
65807
|
+
};
|
|
65808
|
+
exports2.CodeRifts = CodeRifts;
|
|
65809
|
+
function describeComponent(name, value) {
|
|
65810
|
+
const descriptions = {
|
|
65811
|
+
S_contract: "Contract severity score \u2014 measures how severe the breaking changes are",
|
|
65812
|
+
P_break: "Break probability \u2014 likelihood that downstream consumers will break",
|
|
65813
|
+
S_blast_eff: "Blast radius \u2014 how many consumers are affected",
|
|
65814
|
+
S_agent: "Agent safety score \u2014 risk to AI agent tool invocations",
|
|
65815
|
+
S_runtime: "Runtime impact \u2014 risk of runtime failures",
|
|
65816
|
+
ECI: "Ecosystem coupling index \u2014 how tightly coupled the API is",
|
|
65817
|
+
M_eff: "Migration effort \u2014 estimated effort to migrate consumers",
|
|
65818
|
+
D_contract: "Contract distance \u2014 semantic distance between old and new contracts",
|
|
65819
|
+
confidence_score: "Confidence in the analysis result"
|
|
65820
|
+
};
|
|
65821
|
+
return descriptions[name] || `${name} = ${value}`;
|
|
65822
|
+
}
|
|
65823
|
+
}
|
|
65824
|
+
});
|
|
65825
|
+
|
|
65826
|
+
// node_modules/@coderifts/sdk/dist/cjs/decision.js
|
|
65827
|
+
var require_decision = __commonJS({
|
|
65828
|
+
"node_modules/@coderifts/sdk/dist/cjs/decision.js"(exports2) {
|
|
65829
|
+
"use strict";
|
|
65830
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
65831
|
+
exports2.readDecision = readDecision;
|
|
65832
|
+
var EXECUTION_ACTION = {
|
|
65833
|
+
ALLOW: "CONTINUE",
|
|
65834
|
+
WARN: "CONTINUE_WITH_MONITORING",
|
|
65835
|
+
REQUIRE_APPROVAL: "REQUEST_APPROVAL",
|
|
65836
|
+
BLOCK: "STOP"
|
|
65837
|
+
};
|
|
65838
|
+
function isExecutionAction(v) {
|
|
65839
|
+
return v === "CONTINUE" || v === "CONTINUE_WITH_MONITORING" || v === "REQUEST_APPROVAL" || v === "STOP";
|
|
65840
|
+
}
|
|
65841
|
+
function readDecision(response) {
|
|
65842
|
+
if (!response || typeof response !== "object") {
|
|
65843
|
+
return { executionAction: "STOP", decision: null, reason: "UNREADABLE_DECISION" };
|
|
65844
|
+
}
|
|
65845
|
+
const r = response;
|
|
65846
|
+
const env = r.decision_result;
|
|
65847
|
+
if (env && typeof env === "object" && isExecutionAction(env.execution_action)) {
|
|
65848
|
+
const receipt = env.receipt;
|
|
65849
|
+
return {
|
|
65850
|
+
executionAction: env.execution_action,
|
|
65851
|
+
decision: typeof env.decision === "string" ? env.decision : null,
|
|
65852
|
+
envelope: env,
|
|
65853
|
+
receipt: receipt && typeof receipt === "object" ? receipt : void 0
|
|
65854
|
+
};
|
|
65855
|
+
}
|
|
65856
|
+
if (isExecutionAction(r.execution_action)) {
|
|
65857
|
+
return {
|
|
65858
|
+
executionAction: r.execution_action,
|
|
65859
|
+
decision: typeof r.decision === "string" ? r.decision : null
|
|
65860
|
+
};
|
|
65861
|
+
}
|
|
65862
|
+
if (typeof r.decision === "string" && Object.prototype.hasOwnProperty.call(EXECUTION_ACTION, r.decision)) {
|
|
65863
|
+
return { executionAction: EXECUTION_ACTION[r.decision], decision: r.decision };
|
|
65864
|
+
}
|
|
65865
|
+
return {
|
|
65866
|
+
executionAction: "STOP",
|
|
65867
|
+
decision: typeof r.decision === "string" ? r.decision : null,
|
|
65868
|
+
reason: "UNREADABLE_DECISION"
|
|
65869
|
+
};
|
|
65870
|
+
}
|
|
65871
|
+
}
|
|
65872
|
+
});
|
|
65873
|
+
|
|
65874
|
+
// node_modules/@coderifts/sdk/dist/cjs/index.js
|
|
65875
|
+
var require_cjs3 = __commonJS({
|
|
65876
|
+
"node_modules/@coderifts/sdk/dist/cjs/index.js"(exports2) {
|
|
65877
|
+
"use strict";
|
|
65878
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
65879
|
+
exports2.readDecision = exports2.AuthError = exports2.RateLimitError = exports2.TimeoutError = exports2.ApiError = exports2.CodeRiftsError = exports2.CodeRifts = void 0;
|
|
65880
|
+
var client_js_1 = require_client();
|
|
65881
|
+
Object.defineProperty(exports2, "CodeRifts", { enumerable: true, get: function() {
|
|
65882
|
+
return client_js_1.CodeRifts;
|
|
65883
|
+
} });
|
|
65884
|
+
var errors_js_1 = require_errors5();
|
|
65885
|
+
Object.defineProperty(exports2, "CodeRiftsError", { enumerable: true, get: function() {
|
|
65886
|
+
return errors_js_1.CodeRiftsError;
|
|
65887
|
+
} });
|
|
65888
|
+
Object.defineProperty(exports2, "ApiError", { enumerable: true, get: function() {
|
|
65889
|
+
return errors_js_1.ApiError;
|
|
65890
|
+
} });
|
|
65891
|
+
Object.defineProperty(exports2, "TimeoutError", { enumerable: true, get: function() {
|
|
65892
|
+
return errors_js_1.TimeoutError;
|
|
65893
|
+
} });
|
|
65894
|
+
Object.defineProperty(exports2, "RateLimitError", { enumerable: true, get: function() {
|
|
65895
|
+
return errors_js_1.RateLimitError;
|
|
65896
|
+
} });
|
|
65897
|
+
Object.defineProperty(exports2, "AuthError", { enumerable: true, get: function() {
|
|
65898
|
+
return errors_js_1.AuthError;
|
|
65899
|
+
} });
|
|
65900
|
+
var decision_js_1 = require_decision();
|
|
65901
|
+
Object.defineProperty(exports2, "readDecision", { enumerable: true, get: function() {
|
|
65902
|
+
return decision_js_1.readDecision;
|
|
65903
|
+
} });
|
|
65904
|
+
}
|
|
65905
|
+
});
|
|
65906
|
+
|
|
65907
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/detector.js
|
|
65908
|
+
var require_detector = __commonJS({
|
|
65909
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/detector.js"(exports2) {
|
|
65910
|
+
"use strict";
|
|
65911
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
65912
|
+
exports2.builtinDetector = exports2.DETECTOR_VERSION = void 0;
|
|
65913
|
+
var node_zlib_1 = require("node:zlib");
|
|
65914
|
+
exports2.DETECTOR_VERSION = "builtin/1.1.0";
|
|
65915
|
+
var CONTRACT_PATH_RE = [
|
|
65916
|
+
/openapi/i,
|
|
65917
|
+
/swagger/i,
|
|
65918
|
+
/asyncapi/i,
|
|
65919
|
+
/\.graphql$/i,
|
|
65920
|
+
/\.gql$/i,
|
|
65921
|
+
/\.proto$/i,
|
|
65922
|
+
/\.pb($|\.)/i,
|
|
65923
|
+
/(^|\/)[\w.-]*mcp[\w.-]*\.json$/i,
|
|
65924
|
+
/tools-catalog\.json$/i,
|
|
65925
|
+
/schema\.prisma$/i,
|
|
65926
|
+
/(^|\/)migrations?\//i,
|
|
65927
|
+
/(^|\/)alembic\//i,
|
|
65928
|
+
/(^|\/)buf\.ya?ml$/i,
|
|
65929
|
+
/\.spectral\.ya?ml$/i,
|
|
65930
|
+
/(^|\/)\.github\/workflows\//i,
|
|
65931
|
+
/(^|\/)\.husky\//i,
|
|
65932
|
+
/api[-_]?contract/i,
|
|
65933
|
+
/service-definition/i,
|
|
65934
|
+
/(^|\/)contracts?\//i,
|
|
65935
|
+
/schemas?\/components?\//i,
|
|
65936
|
+
/\bcontract\.json$/i,
|
|
65937
|
+
/(^|\/)spec\.(ya?ml|json)$/i,
|
|
65938
|
+
/api[-_/]spec\.(ya?ml|json)$/i,
|
|
65939
|
+
/-api\.(ya?ml|yml)$/i,
|
|
65940
|
+
/current-api/i,
|
|
65941
|
+
/(^|\/)(src\/)?generated\//i,
|
|
65942
|
+
/(^|\/)gen\//i,
|
|
65943
|
+
/\.pb\.go$/i,
|
|
65944
|
+
/openapi\.d\.ts$/i
|
|
65945
|
+
];
|
|
65946
|
+
var NON_SSOT_PATH_RE = [
|
|
65947
|
+
/(^|\/)tests?\//i,
|
|
65948
|
+
/(^|\/)__tests__\//i,
|
|
65949
|
+
/(^|\/)__mocks__\//i,
|
|
65950
|
+
/\/fixtures?\//i,
|
|
65951
|
+
/(^|\/)mocks?\//i,
|
|
65952
|
+
/\.test\.[jt]sx?$/i,
|
|
65953
|
+
/\.spec\.[jt]sx?$/i,
|
|
65954
|
+
/(^|\/)src\/internal\//i,
|
|
65955
|
+
/(^|\/)node_modules\//i
|
|
65956
|
+
];
|
|
65957
|
+
var PROSE_PATH_RE = [/(^|\/)README(\.\w+)?$/i, /(^|\/)CHANGELOG(\.\w+)?$/i, /(^|\/)LICENSE(\.\w+)?$/i, /\.md$/i];
|
|
65958
|
+
var CODE_CONTRACT_PATH_RE = [/(^|\/)src\/routes?\//i, /(^|\/)routes?\//i, /(^|\/)app\/api\//i, /(^|\/)src\/dto\//i, /dto/i, /routers?\//i, /\.prisma$/i, /\.tf$/i, /server\/routers?\//i];
|
|
65959
|
+
var GATE_PATH_RE = [/(^|\/)\.github\/workflows\//i, /(^|\/)\.husky\//i, /\.spectral\.ya?ml$/i, /(^|\/)buf\.ya?ml$/i];
|
|
65960
|
+
var LOCKFILE_RE = /(package-lock\.json|pnpm-lock\.ya?ml|yarn\.lock|composer\.lock|Cargo\.lock)$/i;
|
|
65961
|
+
var CONTRACT_CONTENT_RE = [
|
|
65962
|
+
/\bopenapi\s*[:=]\s*["']?3/i,
|
|
65963
|
+
/["']openapi["']\s*:/i,
|
|
65964
|
+
/\bswagger\s*[:=]/i,
|
|
65965
|
+
/["']swagger["']\s*:/i,
|
|
65966
|
+
/\basyncapi\s*[:=]/i,
|
|
65967
|
+
/["']asyncapi["']\s*:/i,
|
|
65968
|
+
/(^|\n)\s*paths\s*:/i,
|
|
65969
|
+
/["']paths["']\s*:/i,
|
|
65970
|
+
/syntax\s*=\s*["']proto3/i,
|
|
65971
|
+
/(^|\n)\s*message\s+\w+\s*\{/i,
|
|
65972
|
+
/\btype\s+(Query|Mutation|Subscription)\b/i,
|
|
65973
|
+
/["']tools["']\s*:\s*\[/i,
|
|
65974
|
+
/["']inputSchema["']\s*:/i,
|
|
65975
|
+
/\/v\d+\/[\w{}.-]*\s*:/,
|
|
65976
|
+
// versioned route-path key
|
|
65977
|
+
/\bchannels\s*:/i
|
|
65978
|
+
];
|
|
65979
|
+
var CONTRACT_STRUCTURE_RE = [
|
|
65980
|
+
/(get|post|put|delete|patch)\s*:\s*\{?/i,
|
|
65981
|
+
/message\s+\w+\s*\{[^}]*=\s*\d+/i,
|
|
65982
|
+
/\/v\d+\/[\w{}.-]*\s*:/,
|
|
65983
|
+
/"name"\s*:\s*"[^"]+"[\s,}]*"?inputSchema/i
|
|
65984
|
+
];
|
|
65985
|
+
var REAL_CHANGE_RE = [
|
|
65986
|
+
/required\s*:\s*\[/i,
|
|
65987
|
+
/["']required["']\s*:\s*\[/i,
|
|
65988
|
+
/\btype\s*:\s*\w+/i,
|
|
65989
|
+
/nullable\s*:/i,
|
|
65990
|
+
/:\s*\w+!/,
|
|
65991
|
+
/additionalProperties\s*:\s*(true|false)/i,
|
|
65992
|
+
/["']additionalProperties["']/i,
|
|
65993
|
+
/\bDROP\s+COLUMN\b/i,
|
|
65994
|
+
/\bALTER\s+COLUMN\b/i,
|
|
65995
|
+
/alter_column\s*\(/i,
|
|
65996
|
+
/new_column_name/i,
|
|
65997
|
+
/\bRENAME\b/i,
|
|
65998
|
+
/DROP\s+TABLE/i,
|
|
65999
|
+
/@IsString|@IsOptional|response_model|z\.string|@unique/i,
|
|
66000
|
+
/app\.(get|post|put|delete|patch)\s*\(/i,
|
|
66001
|
+
/@router\.(get|post|put|delete|patch)/i,
|
|
66002
|
+
/\/v\d+\//,
|
|
66003
|
+
/continue-on-error|if:\s*false|:\s*off\b|'off'|"off"/i,
|
|
66004
|
+
/\bignore\s*:/i,
|
|
66005
|
+
/(^|\n)\s*breaking\s*:/i
|
|
66006
|
+
];
|
|
66007
|
+
var INERT_KEY_RE = [
|
|
66008
|
+
/^description\s*:/i,
|
|
66009
|
+
/^["']description["']\s*:/i,
|
|
66010
|
+
/^summary\s*:/i,
|
|
66011
|
+
/^title\s*:/i,
|
|
66012
|
+
/^contact\s*:/i,
|
|
66013
|
+
/^name\s*:/i,
|
|
66014
|
+
/^examples?\s*:/i,
|
|
66015
|
+
/^["']examples?["']\s*:/i,
|
|
66016
|
+
/^x-[\w-]+\s*:/i,
|
|
66017
|
+
/^["']x-[\w-]+["']\s*:/i
|
|
66018
|
+
];
|
|
66019
|
+
var READ_ONLY_TOOLS = /* @__PURE__ */ new Set(["read", "grep", "glob", "ls", "cat", "view", "search", "list", "get"]);
|
|
66020
|
+
var FORMATTER_RE = /\b(prettier|eslint\s+--fix|gofmt|rustfmt|black|clang-format|dprint)\b/i;
|
|
66021
|
+
var GATE_KEYWORD_RE = /coderifts|agent-guard|contract-check|contract\b|preflight|spectral|\bbuf\b/i;
|
|
66022
|
+
function anyMatch(res, s) {
|
|
66023
|
+
return res.some((r) => r.test(s));
|
|
66024
|
+
}
|
|
66025
|
+
function argString(args) {
|
|
66026
|
+
if (args == null)
|
|
66027
|
+
return "";
|
|
66028
|
+
if (typeof args === "string")
|
|
66029
|
+
return args;
|
|
66030
|
+
try {
|
|
66031
|
+
return JSON.stringify(args);
|
|
66032
|
+
} catch {
|
|
66033
|
+
return "";
|
|
66034
|
+
}
|
|
66035
|
+
}
|
|
66036
|
+
function changeText(call) {
|
|
66037
|
+
const parts = [];
|
|
66038
|
+
if (call.diff)
|
|
66039
|
+
parts.push(call.diff);
|
|
66040
|
+
const a = call.arguments;
|
|
66041
|
+
if (a && typeof a === "object") {
|
|
66042
|
+
for (const k of ["new_string", "old_string", "contents", "content", "patch", "command"]) {
|
|
66043
|
+
const v = a[k];
|
|
66044
|
+
if (typeof v === "string")
|
|
66045
|
+
parts.push(v);
|
|
66046
|
+
}
|
|
66047
|
+
const edits = a.edits;
|
|
66048
|
+
if (Array.isArray(edits))
|
|
66049
|
+
for (const e of edits)
|
|
66050
|
+
parts.push(argString(e));
|
|
66051
|
+
}
|
|
66052
|
+
return parts.join("\n");
|
|
66053
|
+
}
|
|
66054
|
+
function commandText(call) {
|
|
66055
|
+
const a = call.arguments;
|
|
66056
|
+
const c = a && typeof a === "object" ? a.command : void 0;
|
|
66057
|
+
return typeof c === "string" ? c : "";
|
|
66058
|
+
}
|
|
66059
|
+
function allPaths(call) {
|
|
66060
|
+
const out = [...call.filesTouched || []];
|
|
66061
|
+
const a = call.arguments;
|
|
66062
|
+
if (a && typeof a === "object" && typeof a.path === "string")
|
|
66063
|
+
out.push(a.path);
|
|
66064
|
+
return out;
|
|
66065
|
+
}
|
|
66066
|
+
function isContractPath(p) {
|
|
66067
|
+
if (anyMatch(NON_SSOT_PATH_RE, p))
|
|
66068
|
+
return false;
|
|
66069
|
+
if (anyMatch(PROSE_PATH_RE, p))
|
|
66070
|
+
return false;
|
|
66071
|
+
return anyMatch(CONTRACT_PATH_RE, p);
|
|
66072
|
+
}
|
|
66073
|
+
function changedLines(call) {
|
|
66074
|
+
if (call.diff) {
|
|
66075
|
+
return call.diff.split("\n").filter((l) => l.startsWith("+") || l.startsWith("-")).map((l) => l.slice(1));
|
|
66076
|
+
}
|
|
66077
|
+
const out = [];
|
|
66078
|
+
const a = call.arguments;
|
|
66079
|
+
const pushSetDiff = (oldS, newS) => {
|
|
66080
|
+
const oldL = typeof oldS === "string" ? oldS.split("\n") : [];
|
|
66081
|
+
const newL = typeof newS === "string" ? newS.split("\n") : [];
|
|
66082
|
+
const oldSet = new Set(oldL.map((l) => l.trim()));
|
|
66083
|
+
const newSet = new Set(newL.map((l) => l.trim()));
|
|
66084
|
+
for (const l of newL)
|
|
66085
|
+
if (!oldSet.has(l.trim()))
|
|
66086
|
+
out.push(l);
|
|
66087
|
+
for (const l of oldL)
|
|
66088
|
+
if (!newSet.has(l.trim()))
|
|
66089
|
+
out.push(l);
|
|
66090
|
+
};
|
|
66091
|
+
if (a && typeof a === "object") {
|
|
66092
|
+
pushSetDiff(a.old_string, a.new_string);
|
|
66093
|
+
const contents = a.contents ?? a.content;
|
|
66094
|
+
if (typeof contents === "string")
|
|
66095
|
+
for (const l of contents.split("\n"))
|
|
66096
|
+
out.push(l);
|
|
66097
|
+
const patch = a.patch;
|
|
66098
|
+
if (typeof patch === "string") {
|
|
66099
|
+
for (const l of patch.split("\n"))
|
|
66100
|
+
if (l.startsWith("+") || l.startsWith("-"))
|
|
66101
|
+
out.push(l.slice(1));
|
|
66102
|
+
}
|
|
66103
|
+
const edits = a.edits;
|
|
66104
|
+
if (Array.isArray(edits)) {
|
|
66105
|
+
for (const e of edits)
|
|
66106
|
+
if (e && typeof e === "object")
|
|
66107
|
+
pushSetDiff(e.old_string, e.new_string);
|
|
66108
|
+
}
|
|
66109
|
+
}
|
|
66110
|
+
return out;
|
|
66111
|
+
}
|
|
66112
|
+
function migrationDestructive(text) {
|
|
66113
|
+
return /\bDROP\s+COLUMN\b|\bALTER\s+COLUMN\b|new_column_name|alter_column|\bRENAME\b|DROP\s+TABLE|DROP\s+CONSTRAINT/i.test(text);
|
|
66114
|
+
}
|
|
66115
|
+
function migrationIndexOnly(text) {
|
|
66116
|
+
return /CREATE\s+INDEX/i.test(text) && !migrationDestructive(text) && !/ADD\s+COLUMN|DROP\b/i.test(text);
|
|
66117
|
+
}
|
|
66118
|
+
function gateDisabled(call) {
|
|
66119
|
+
const paths = allPaths(call);
|
|
66120
|
+
if (!paths.some((p) => anyMatch(GATE_PATH_RE, p)))
|
|
66121
|
+
return false;
|
|
66122
|
+
const text = changeText(call);
|
|
66123
|
+
if (!GATE_KEYWORD_RE.test(text))
|
|
66124
|
+
return false;
|
|
66125
|
+
const lines = changedLines(call);
|
|
66126
|
+
const commentedOut = lines.some((l) => /^\s*(#|\/\/)/.test(l) && GATE_KEYWORD_RE.test(l));
|
|
66127
|
+
const weakened = anyMatch(REAL_CHANGE_RE, text) || /continue-on-error|if:\s*false|:\s*off\b|ignore\s*:/i.test(text);
|
|
66128
|
+
return commentedOut || weakened;
|
|
66129
|
+
}
|
|
66130
|
+
function lockfileContractChange(call) {
|
|
66131
|
+
const paths = allPaths(call);
|
|
66132
|
+
if (!paths.some((p) => LOCKFILE_RE.test(p)))
|
|
66133
|
+
return false;
|
|
66134
|
+
const text = changeText(call);
|
|
66135
|
+
const contractPkg = /@[\w.-]+\/(openapi|graphql|proto|asyncapi|schema)\b|(openapi|graphql|proto|asyncapi|schema)@\d/i.test(text);
|
|
66136
|
+
if (!contractPkg)
|
|
66137
|
+
return false;
|
|
66138
|
+
return /"resolved"\s*:/i.test(text) || /@\d+\.\d+\.\d+/.test(text) || /@\d+['":]/.test(text);
|
|
66139
|
+
}
|
|
66140
|
+
function isInertOnly(call) {
|
|
66141
|
+
const text = changeText(call);
|
|
66142
|
+
const paths = allPaths(call);
|
|
66143
|
+
if (paths.some((p) => LOCKFILE_RE.test(p)) && !lockfileContractChange(call)) {
|
|
66144
|
+
if (/"integrity"\s*:/i.test(text) && !/"resolved"\s*:/i.test(text))
|
|
66145
|
+
return true;
|
|
66146
|
+
}
|
|
66147
|
+
if (paths.some((p) => /migrations?\/|alembic\//i.test(p)) && migrationIndexOnly(text))
|
|
66148
|
+
return true;
|
|
66149
|
+
if (paths.some((p) => anyMatch(GATE_PATH_RE, p))) {
|
|
66150
|
+
if (!GATE_KEYWORD_RE.test(text) && !anyMatch(REAL_CHANGE_RE, text))
|
|
66151
|
+
return true;
|
|
66152
|
+
return false;
|
|
66153
|
+
}
|
|
66154
|
+
const cmd = commandText(call);
|
|
66155
|
+
if (cmd && FORMATTER_RE.test(cmd))
|
|
66156
|
+
return true;
|
|
66157
|
+
if (/\b(examples?|value)\s*:/i.test(text) && !anyMatch(REAL_CHANGE_RE, text))
|
|
66158
|
+
return true;
|
|
66159
|
+
const lines = changedLines(call);
|
|
66160
|
+
if (lines.length === 0)
|
|
66161
|
+
return false;
|
|
66162
|
+
let sawReal = false;
|
|
66163
|
+
let sawInert = false;
|
|
66164
|
+
for (const raw of lines) {
|
|
66165
|
+
const t = raw.trim();
|
|
66166
|
+
if (t === "") {
|
|
66167
|
+
sawInert = true;
|
|
66168
|
+
continue;
|
|
66169
|
+
}
|
|
66170
|
+
if (/^#|^\/\/|^\/\*|\*\/|^\*/.test(t)) {
|
|
66171
|
+
sawInert = true;
|
|
66172
|
+
continue;
|
|
66173
|
+
}
|
|
66174
|
+
if (/^```/.test(t)) {
|
|
66175
|
+
sawInert = true;
|
|
66176
|
+
continue;
|
|
66177
|
+
}
|
|
66178
|
+
if (/^["'].*["']$/.test(t) && !t.includes(":")) {
|
|
66179
|
+
sawInert = true;
|
|
66180
|
+
continue;
|
|
66181
|
+
}
|
|
66182
|
+
if (/generated|timestamp/i.test(t)) {
|
|
66183
|
+
sawInert = true;
|
|
66184
|
+
continue;
|
|
66185
|
+
}
|
|
66186
|
+
if (anyMatch(INERT_KEY_RE, t)) {
|
|
66187
|
+
sawInert = true;
|
|
66188
|
+
continue;
|
|
66189
|
+
}
|
|
66190
|
+
if (anyMatch(REAL_CHANGE_RE, t) || anyMatch(CONTRACT_STRUCTURE_RE, t) || anyMatch(CONTRACT_CONTENT_RE, t)) {
|
|
66191
|
+
sawReal = true;
|
|
66192
|
+
continue;
|
|
66193
|
+
}
|
|
66194
|
+
if (/^[\w"']+\??\s*:\s*\S/.test(t)) {
|
|
66195
|
+
sawReal = true;
|
|
66196
|
+
continue;
|
|
66197
|
+
}
|
|
66198
|
+
}
|
|
66199
|
+
return sawInert && !sawReal;
|
|
66200
|
+
}
|
|
66201
|
+
function realChangePresent(call) {
|
|
66202
|
+
const text = changeText(call);
|
|
66203
|
+
if (migrationDestructive(text))
|
|
66204
|
+
return true;
|
|
66205
|
+
if (gateDisabled(call))
|
|
66206
|
+
return true;
|
|
66207
|
+
if (lockfileContractChange(call))
|
|
66208
|
+
return true;
|
|
66209
|
+
for (const raw of changedLines(call)) {
|
|
66210
|
+
const t = raw.trim();
|
|
66211
|
+
if (anyMatch(INERT_KEY_RE, t))
|
|
66212
|
+
continue;
|
|
66213
|
+
if (anyMatch(REAL_CHANGE_RE, t))
|
|
66214
|
+
return true;
|
|
66215
|
+
if (/^[\w"']+\??\s*:\s*\S/.test(t) && !/^(paths|components|info|servers|channels|tools|get|post|put|delete|patch)\s*:/i.test(t))
|
|
66216
|
+
return true;
|
|
66217
|
+
}
|
|
66218
|
+
return false;
|
|
66219
|
+
}
|
|
66220
|
+
function intentMentionsContract(intent) {
|
|
66221
|
+
if (!intent)
|
|
66222
|
+
return false;
|
|
66223
|
+
return /openapi|swagger|graphql|protobuf|\bproto\b|asyncapi|mcp\s*manifest|mcp\.json|json\s*schema|\bschema\b|required\s+field|\bendpoint\b|wire\s*format|api\s*spec|contract\s*(file|change|surface)/i.test(intent);
|
|
66224
|
+
}
|
|
66225
|
+
function commandMutatesContract(call) {
|
|
66226
|
+
const cmd = commandText(call);
|
|
66227
|
+
if (!cmd)
|
|
66228
|
+
return false;
|
|
66229
|
+
if (FORMATTER_RE.test(cmd))
|
|
66230
|
+
return false;
|
|
66231
|
+
const touchesContract = allPaths(call).some(isContractPath) || /(>|>>|-o\s|mv\s|ln\s+-sf?\s|git\s+mv\s|cp\s)[^\n|]*(openapi|swagger|asyncapi|\.graphql|\.gql|\.proto|\.pb\b|mcp[.-]?\w*\.json|schema\.prisma|spec\.(ya?ml|json))/i.test(cmd) || anyMatch(CONTRACT_CONTENT_RE, cmd);
|
|
66232
|
+
const mutates = /(>|>>|\bmv\b|\bcp\b|\bln\s|git\s+mv|curl|wget|-o\b|base64\s+-d|xxd|\bjq\b|\bsed\b|\btee\b|echo|printf|\bcat\b)/i.test(cmd);
|
|
66233
|
+
return touchesContract && mutates;
|
|
66234
|
+
}
|
|
66235
|
+
var DEEP_MAX_DEPTH = 8;
|
|
66236
|
+
var DEEP_MAX_BYTES = 262144;
|
|
66237
|
+
var DEEP_DECODE_MAX_BYTES = 65536;
|
|
66238
|
+
var DEEP_DECODE_LEVELS = 3;
|
|
66239
|
+
var OPAQUE_MIN_LEN = 40;
|
|
66240
|
+
function looksLikePath(v) {
|
|
66241
|
+
return v.length > 0 && v.length <= 256 && !/[\n\r{}<>]/.test(v) && /(^|\/)[\w.@-]+\.[A-Za-z0-9]+$/.test(v.trim());
|
|
66242
|
+
}
|
|
66243
|
+
function decodeCandidates(v) {
|
|
66244
|
+
const out = [];
|
|
66245
|
+
const push = (s) => {
|
|
66246
|
+
if (s && s.length > 0 && s.length <= DEEP_DECODE_MAX_BYTES)
|
|
66247
|
+
out.push(s);
|
|
66248
|
+
};
|
|
66249
|
+
const compact = v.replace(/\s+/g, "");
|
|
66250
|
+
if (compact.length >= 16 && compact.length % 4 === 0 && /^[A-Za-z0-9+/]+={0,2}$/.test(compact)) {
|
|
66251
|
+
try {
|
|
66252
|
+
push(Buffer.from(compact, "base64").toString("utf8"));
|
|
66253
|
+
} catch {
|
|
66254
|
+
}
|
|
66255
|
+
try {
|
|
66256
|
+
const b = Buffer.from(compact, "base64");
|
|
66257
|
+
push((0, node_zlib_1.gunzipSync)(b).toString("utf8"));
|
|
66258
|
+
} catch {
|
|
66259
|
+
}
|
|
66260
|
+
}
|
|
66261
|
+
if (compact.length >= 16 && compact.length % 2 === 0 && /^[0-9a-fA-F]+$/.test(compact)) {
|
|
66262
|
+
try {
|
|
66263
|
+
push(Buffer.from(compact, "hex").toString("utf8"));
|
|
66264
|
+
} catch {
|
|
66265
|
+
}
|
|
66266
|
+
}
|
|
66267
|
+
if (/%[0-9a-fA-F]{2}/.test(v)) {
|
|
66268
|
+
try {
|
|
66269
|
+
push(decodeURIComponent(v));
|
|
66270
|
+
} catch {
|
|
66271
|
+
}
|
|
66272
|
+
}
|
|
66273
|
+
if (/\\["\\/]|^\s*"/.test(v)) {
|
|
66274
|
+
try {
|
|
66275
|
+
const p = JSON.parse(v);
|
|
66276
|
+
if (typeof p === "string")
|
|
66277
|
+
push(p);
|
|
66278
|
+
} catch {
|
|
66279
|
+
}
|
|
66280
|
+
}
|
|
66281
|
+
return out;
|
|
66282
|
+
}
|
|
66283
|
+
function looksEncoded(v) {
|
|
66284
|
+
const c = v.replace(/\s+/g, "");
|
|
66285
|
+
if (c.length < OPAQUE_MIN_LEN)
|
|
66286
|
+
return false;
|
|
66287
|
+
return /^[A-Za-z0-9+/]+={0,2}$/.test(c) && c.length % 4 === 0 || /^[0-9a-fA-F]+$/.test(c) && c.length % 2 === 0;
|
|
66288
|
+
}
|
|
66289
|
+
function deepArgScan(call) {
|
|
66290
|
+
const acc = { contractContent: false, pathContractSsot: false, pathNonSsot: false, pathLikeCount: 0, proseCount: 0, opaque: false, capHit: false };
|
|
66291
|
+
let budget = DEEP_MAX_BYTES;
|
|
66292
|
+
const scanString = (s) => {
|
|
66293
|
+
if (looksLikePath(s)) {
|
|
66294
|
+
acc.pathLikeCount++;
|
|
66295
|
+
if (anyMatch(NON_SSOT_PATH_RE, s))
|
|
66296
|
+
acc.pathNonSsot = true;
|
|
66297
|
+
else if (anyMatch(PROSE_PATH_RE, s))
|
|
66298
|
+
acc.proseCount++;
|
|
66299
|
+
else if (isContractPath(s))
|
|
66300
|
+
acc.pathContractSsot = true;
|
|
66301
|
+
return;
|
|
66302
|
+
}
|
|
66303
|
+
if (anyMatch(CONTRACT_CONTENT_RE, s) || anyMatch(CONTRACT_STRUCTURE_RE, s)) {
|
|
66304
|
+
acc.contractContent = true;
|
|
66305
|
+
return;
|
|
66306
|
+
}
|
|
66307
|
+
let level = [s];
|
|
66308
|
+
for (let d = 0; d < DEEP_DECODE_LEVELS && !acc.contractContent; d++) {
|
|
66309
|
+
const next = [];
|
|
66310
|
+
for (const val of level) {
|
|
66311
|
+
for (const dec of decodeCandidates(val)) {
|
|
66312
|
+
if (anyMatch(CONTRACT_CONTENT_RE, dec) || anyMatch(CONTRACT_STRUCTURE_RE, dec)) {
|
|
66313
|
+
acc.contractContent = true;
|
|
66314
|
+
break;
|
|
66315
|
+
}
|
|
66316
|
+
next.push(dec);
|
|
66317
|
+
}
|
|
66318
|
+
if (acc.contractContent)
|
|
66319
|
+
break;
|
|
66320
|
+
}
|
|
66321
|
+
level = next;
|
|
66322
|
+
}
|
|
66323
|
+
if (!acc.contractContent && looksEncoded(s) && level.every((x) => !isReadableText(x)))
|
|
66324
|
+
acc.opaque = true;
|
|
66325
|
+
};
|
|
66326
|
+
const walk = (node, depth) => {
|
|
66327
|
+
if (acc.capHit || budget <= 0)
|
|
66328
|
+
return;
|
|
66329
|
+
if (depth > DEEP_MAX_DEPTH) {
|
|
66330
|
+
acc.capHit = true;
|
|
66331
|
+
return;
|
|
66332
|
+
}
|
|
66333
|
+
if (typeof node === "string") {
|
|
66334
|
+
budget -= node.length;
|
|
66335
|
+
if (budget <= 0) {
|
|
66336
|
+
acc.capHit = true;
|
|
66337
|
+
return;
|
|
66338
|
+
}
|
|
66339
|
+
scanString(node);
|
|
66340
|
+
} else if (Array.isArray(node)) {
|
|
66341
|
+
for (const el of node) {
|
|
66342
|
+
if (acc.capHit)
|
|
66343
|
+
break;
|
|
66344
|
+
walk(el, depth + 1);
|
|
66345
|
+
}
|
|
66346
|
+
} else if (node && typeof node === "object") {
|
|
66347
|
+
for (const val of Object.values(node)) {
|
|
66348
|
+
if (acc.capHit)
|
|
66349
|
+
break;
|
|
66350
|
+
walk(val, depth + 1);
|
|
66351
|
+
}
|
|
66352
|
+
}
|
|
66353
|
+
};
|
|
66354
|
+
try {
|
|
66355
|
+
walk(call.arguments, 0);
|
|
66356
|
+
} catch {
|
|
66357
|
+
acc.capHit = true;
|
|
66358
|
+
}
|
|
66359
|
+
return acc;
|
|
66360
|
+
}
|
|
66361
|
+
function isReadableText(s) {
|
|
66362
|
+
if (!s)
|
|
66363
|
+
return false;
|
|
66364
|
+
let printable = 0;
|
|
66365
|
+
const n = Math.min(s.length, 512);
|
|
66366
|
+
for (let i = 0; i < n; i++) {
|
|
66367
|
+
const c = s.charCodeAt(i);
|
|
66368
|
+
if (c === 9 || c === 10 || c === 13 || c >= 32 && c < 127)
|
|
66369
|
+
printable++;
|
|
66370
|
+
}
|
|
66371
|
+
return printable / n > 0.85;
|
|
66372
|
+
}
|
|
66373
|
+
exports2.builtinDetector = {
|
|
66374
|
+
version: exports2.DETECTOR_VERSION,
|
|
66375
|
+
detect(call) {
|
|
66376
|
+
const signals = [];
|
|
66377
|
+
const artifacts = Array.isArray(call.artifacts) ? call.artifacts : [];
|
|
66378
|
+
if (artifacts.length > 0)
|
|
66379
|
+
return { trigger: true, artifacts, signals: ["explicit_artifacts"], confident: true };
|
|
66380
|
+
if (READ_ONLY_TOOLS.has(String(call.toolName).toLowerCase()) && !commandMutatesContract(call)) {
|
|
66381
|
+
return { trigger: false, artifacts: [], signals: ["non_mutating_tool"], confident: true };
|
|
66382
|
+
}
|
|
66383
|
+
const paths = allPaths(call);
|
|
66384
|
+
const contractPath = paths.some(isContractPath);
|
|
66385
|
+
const codeContractPath = paths.some((p) => anyMatch(CODE_CONTRACT_PATH_RE, p) && !anyMatch(NON_SSOT_PATH_RE, p));
|
|
66386
|
+
const change = changeText(call);
|
|
66387
|
+
const inProse = paths.length > 0 && paths.every((p) => anyMatch(PROSE_PATH_RE, p));
|
|
66388
|
+
const contentMarker = anyMatch(CONTRACT_CONTENT_RE, change) && !paths.some((p) => anyMatch(NON_SSOT_PATH_RE, p)) && !inProse;
|
|
66389
|
+
const shellMutation = commandMutatesContract(call);
|
|
66390
|
+
const gate = gateDisabled(call);
|
|
66391
|
+
const lockContract = lockfileContractChange(call);
|
|
66392
|
+
const contractSurface = contractPath || contentMarker || shellMutation || codeContractPath || gate || lockContract;
|
|
66393
|
+
if (contractSurface) {
|
|
66394
|
+
if (shellMutation) {
|
|
66395
|
+
signals.push("shell_mutates_contract");
|
|
66396
|
+
return { trigger: true, artifacts, signals, confident: true };
|
|
66397
|
+
}
|
|
66398
|
+
if (gate) {
|
|
66399
|
+
signals.push("contract_gate_disabled");
|
|
66400
|
+
return { trigger: true, artifacts, signals, confident: true };
|
|
66401
|
+
}
|
|
66402
|
+
if (lockContract) {
|
|
66403
|
+
signals.push("lockfile_contract_redirect");
|
|
66404
|
+
return { trigger: true, artifacts, signals, confident: true };
|
|
66405
|
+
}
|
|
66406
|
+
if (isInertOnly(call)) {
|
|
66407
|
+
signals.push("inert_change_only");
|
|
66408
|
+
return { trigger: false, artifacts: [], signals, confident: true };
|
|
66409
|
+
}
|
|
66410
|
+
if (realChangePresent(call) || contentMarker || anyMatch(CONTRACT_STRUCTURE_RE, change)) {
|
|
66411
|
+
signals.push("contract_change");
|
|
66412
|
+
return { trigger: true, artifacts, signals, confident: true };
|
|
66413
|
+
}
|
|
66414
|
+
signals.push("ambiguous_contract_surface");
|
|
66415
|
+
return { trigger: true, artifacts, signals, confident: false };
|
|
66416
|
+
}
|
|
66417
|
+
const deep = deepArgScan(call);
|
|
66418
|
+
if (deep.contractContent || deep.pathContractSsot) {
|
|
66419
|
+
const deepInProse = deep.pathLikeCount > 0 && deep.proseCount === deep.pathLikeCount && !deep.pathContractSsot;
|
|
66420
|
+
if (!deep.pathNonSsot && !deepInProse && !isInertOnly(call)) {
|
|
66421
|
+
signals.push(deep.contractContent ? "arguments_deep_contract" : "arguments_deep_path");
|
|
66422
|
+
return { trigger: true, artifacts, signals, confident: false };
|
|
66423
|
+
}
|
|
66424
|
+
}
|
|
66425
|
+
if (deep.opaque || deep.capHit) {
|
|
66426
|
+
signals.push(deep.capHit ? "arguments_scan_capped" : "arguments_opaque");
|
|
66427
|
+
return { trigger: true, artifacts, signals, confident: false };
|
|
66428
|
+
}
|
|
66429
|
+
if (intentMentionsContract(call.intent)) {
|
|
66430
|
+
signals.push("intent_contract_reference");
|
|
66431
|
+
return { trigger: true, artifacts, signals, confident: false };
|
|
66432
|
+
}
|
|
66433
|
+
signals.push("no_contract_signal");
|
|
66434
|
+
return { trigger: false, artifacts: [], signals, confident: true };
|
|
66435
|
+
}
|
|
66436
|
+
};
|
|
66437
|
+
}
|
|
66438
|
+
});
|
|
66439
|
+
|
|
66440
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/receipt-binding.js
|
|
66441
|
+
var require_receipt_binding = __commonJS({
|
|
66442
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/receipt-binding.js"(exports2) {
|
|
66443
|
+
"use strict";
|
|
66444
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
66445
|
+
exports2.canonicalJson = canonicalJson;
|
|
66446
|
+
exports2.computeBodyHash = computeBodyHash;
|
|
66447
|
+
exports2.bindReceiptToEnvelope = bindReceiptToEnvelope;
|
|
66448
|
+
var node_crypto_1 = require("node:crypto");
|
|
66449
|
+
function canonicalJson(value) {
|
|
66450
|
+
return encode(value);
|
|
66451
|
+
}
|
|
66452
|
+
function encode(value) {
|
|
66453
|
+
if (value === null)
|
|
66454
|
+
return "null";
|
|
66455
|
+
const t = typeof value;
|
|
66456
|
+
if (t === "boolean" || t === "string")
|
|
66457
|
+
return JSON.stringify(value);
|
|
66458
|
+
if (t === "number") {
|
|
66459
|
+
if (!Number.isFinite(value))
|
|
66460
|
+
throw new TypeError("canonicalJson: non-finite number is not representable");
|
|
66461
|
+
return JSON.stringify(value);
|
|
66462
|
+
}
|
|
66463
|
+
if (t === "undefined")
|
|
66464
|
+
throw new TypeError("canonicalJson: undefined is not representable (omit the key instead)");
|
|
66465
|
+
if (Array.isArray(value))
|
|
66466
|
+
return `[${value.map(encode).join(",")}]`;
|
|
66467
|
+
if (t === "object") {
|
|
66468
|
+
const obj = value;
|
|
66469
|
+
const keys = Object.keys(obj).sort();
|
|
66470
|
+
return `{${keys.map((k) => `${JSON.stringify(k)}:${encode(obj[k])}`).join(",")}}`;
|
|
66471
|
+
}
|
|
66472
|
+
throw new TypeError(`canonicalJson: unsupported type ${t}`);
|
|
66473
|
+
}
|
|
66474
|
+
function sha256hex(s) {
|
|
66475
|
+
return (0, node_crypto_1.createHash)("sha256").update(s).digest("hex");
|
|
66476
|
+
}
|
|
66477
|
+
function computeBodyHash(envelope) {
|
|
66478
|
+
const rest = { ...envelope };
|
|
66479
|
+
delete rest.receipt;
|
|
66480
|
+
delete rest.decision_body_hash;
|
|
66481
|
+
return `sha256:${sha256hex(canonicalJson(rest))}`;
|
|
66482
|
+
}
|
|
66483
|
+
function bindReceiptToEnvelope(envelope, vr, ctx = {}) {
|
|
66484
|
+
if (!envelope)
|
|
66485
|
+
return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: "no envelope" };
|
|
66486
|
+
if (!vr || vr.valid !== true)
|
|
66487
|
+
return { ok: false, cause: "RECEIPT_UNVERIFIED", detail: `valid=${vr ? vr.valid : "none"}` };
|
|
66488
|
+
if (vr.status !== "VERIFIED_CURRENT") {
|
|
66489
|
+
return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: `status ${vr.status ?? "unknown"} != VERIFIED_CURRENT` };
|
|
66490
|
+
}
|
|
66491
|
+
const payload = vr.payload || {};
|
|
66492
|
+
const localBh = computeBodyHash(envelope);
|
|
66493
|
+
if (typeof payload.bh !== "string" || payload.bh !== localBh) {
|
|
66494
|
+
return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: "decision_body_hash mismatch (receipt was signed over a different envelope)" };
|
|
66495
|
+
}
|
|
66496
|
+
if (typeof payload.fp !== "string" || payload.fp !== envelope.fingerprint) {
|
|
66497
|
+
return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: "verdict_fingerprint mismatch" };
|
|
66498
|
+
}
|
|
66499
|
+
const requestedOp = ctx.operation ?? "tool_call";
|
|
66500
|
+
if (envelope.operation != null && requestedOp != null && envelope.operation !== requestedOp) {
|
|
66501
|
+
return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: `operation ${String(envelope.operation)} != ${String(requestedOp)}` };
|
|
66502
|
+
}
|
|
66503
|
+
if (ctx.environment != null && envelope.environment != null && envelope.environment !== ctx.environment) {
|
|
66504
|
+
return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: `environment ${String(envelope.environment)} != ${String(ctx.environment)}` };
|
|
66505
|
+
}
|
|
66506
|
+
if (ctx.audience != null && envelope.audience != null && envelope.audience !== ctx.audience) {
|
|
66507
|
+
return { ok: false, cause: "RECEIPT_ENVELOPE_MISMATCH", detail: `audience ${String(envelope.audience)} != ${String(ctx.audience)}` };
|
|
66508
|
+
}
|
|
66509
|
+
return { ok: true };
|
|
66510
|
+
}
|
|
66511
|
+
}
|
|
66512
|
+
});
|
|
66513
|
+
|
|
66514
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/enforcement-gate.js
|
|
66515
|
+
var require_enforcement_gate = __commonJS({
|
|
66516
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/enforcement-gate.js"(exports2) {
|
|
66517
|
+
"use strict";
|
|
66518
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
66519
|
+
exports2.computeArtifactDigest = computeArtifactDigest;
|
|
66520
|
+
exports2.computeBundleFingerprint = computeBundleFingerprint;
|
|
66521
|
+
exports2.evaluateEnvelope = evaluateEnvelope;
|
|
66522
|
+
var node_crypto_1 = require("node:crypto");
|
|
66523
|
+
var DECISION_RANK = { ALLOW: 0, WARN: 1, REQUIRE_APPROVAL: 2, BLOCK: 3 };
|
|
66524
|
+
var ACTION_TO_DECISION = {
|
|
66525
|
+
CONTINUE: "ALLOW",
|
|
66526
|
+
CONTINUE_WITH_MONITORING: "WARN",
|
|
66527
|
+
REQUEST_APPROVAL: "REQUIRE_APPROVAL",
|
|
66528
|
+
STOP: "BLOCK"
|
|
66529
|
+
};
|
|
66530
|
+
var DECISION_TO_ACTION = {
|
|
66531
|
+
ALLOW: "CONTINUE",
|
|
66532
|
+
WARN: "CONTINUE_WITH_MONITORING",
|
|
66533
|
+
REQUIRE_APPROVAL: "REQUEST_APPROVAL",
|
|
66534
|
+
BLOCK: "STOP"
|
|
66535
|
+
};
|
|
66536
|
+
function isDecision(v) {
|
|
66537
|
+
return v === "ALLOW" || v === "WARN" || v === "REQUIRE_APPROVAL" || v === "BLOCK";
|
|
66538
|
+
}
|
|
66539
|
+
function isAction(v) {
|
|
66540
|
+
return v === "CONTINUE" || v === "CONTINUE_WITH_MONITORING" || v === "REQUEST_APPROVAL" || v === "STOP";
|
|
66541
|
+
}
|
|
66542
|
+
var NUL = "";
|
|
66543
|
+
function sha256hex(s) {
|
|
66544
|
+
return (0, node_crypto_1.createHash)("sha256").update(s).digest("hex");
|
|
66545
|
+
}
|
|
66546
|
+
function specStr(v) {
|
|
66547
|
+
return v == null ? "" : typeof v === "string" ? v : JSON.stringify(v);
|
|
66548
|
+
}
|
|
66549
|
+
function computeArtifactDigest(artifacts) {
|
|
66550
|
+
const preimage = artifacts.slice().sort((a, b) => `${a.type}${NUL}${a.id}` < `${b.type}${NUL}${b.id}` ? -1 : 1).map((a) => `${sha256hex(specStr(a.before))}${sha256hex(specStr(a.after))}`).join(NUL);
|
|
66551
|
+
return `sha256:${sha256hex(preimage)}`;
|
|
66552
|
+
}
|
|
66553
|
+
function computeBundleFingerprint(artifacts) {
|
|
66554
|
+
const parts = artifacts.slice().sort((a, b) => `${a.type}${NUL}${a.id}` < `${b.type}${NUL}${b.id}` ? -1 : 1).map((a) => [a.type, a.id, sha256hex(specStr(a.before)), sha256hex(specStr(a.after))].join(NUL));
|
|
66555
|
+
return `sha256:${sha256hex(parts.join(NUL))}`;
|
|
66556
|
+
}
|
|
66557
|
+
function evaluateEnvelope(response, envelope, executionAction, sentArtifacts) {
|
|
66558
|
+
const dec = envelope.decision;
|
|
66559
|
+
if (!isDecision(dec)) {
|
|
66560
|
+
return { verdict: "fail-closed", cause: "DECISION_INCONSISTENT", detail: `decision=${JSON.stringify(dec)} is missing/invalid` };
|
|
66561
|
+
}
|
|
66562
|
+
const signals = [dec, ACTION_TO_DECISION[executionAction]];
|
|
66563
|
+
const top = response && typeof response === "object" ? response : {};
|
|
66564
|
+
if (isDecision(top.decision))
|
|
66565
|
+
signals.push(top.decision);
|
|
66566
|
+
if (isAction(top.execution_action))
|
|
66567
|
+
signals.push(ACTION_TO_DECISION[top.execution_action]);
|
|
66568
|
+
const effective = signals.reduce((a, b) => DECISION_RANK[b] > DECISION_RANK[a] ? b : a);
|
|
66569
|
+
if (DECISION_RANK[effective] >= DECISION_RANK.REQUIRE_APPROVAL) {
|
|
66570
|
+
return { verdict: "block-strict", decision: effective };
|
|
66571
|
+
}
|
|
66572
|
+
if (DECISION_TO_ACTION[dec] !== executionAction) {
|
|
66573
|
+
return { verdict: "fail-closed", cause: "DECISION_INCONSISTENT", detail: `decision=${dec} \u2260 execution_action=${executionAction}` };
|
|
66574
|
+
}
|
|
66575
|
+
if (envelope.safe_for_agent === false) {
|
|
66576
|
+
return { verdict: "fail-closed", cause: "DECISION_INCONSISTENT", detail: "safe_for_agent=false on an allow-class decision" };
|
|
66577
|
+
}
|
|
66578
|
+
const degradedReasons = envelope.degraded_reasons;
|
|
66579
|
+
if (envelope.analysis_complete === false || Array.isArray(degradedReasons) && degradedReasons.length > 0 || envelope.degraded === true || envelope.coverage_gap === true) {
|
|
66580
|
+
return { verdict: "fail-closed", cause: "ANALYSIS_DEGRADED", detail: "analysis degraded / incomplete" };
|
|
66581
|
+
}
|
|
66582
|
+
if (Array.isArray(sentArtifacts) && sentArtifacts.length > 0 && typeof envelope.artifact_digest === "string" && envelope.artifact_digest !== computeArtifactDigest(sentArtifacts)) {
|
|
66583
|
+
return { verdict: "fail-closed", cause: "ARTIFACT_MISMATCH", detail: "artifact_digest \u2260 locally-recomputed digest of sent artifacts" };
|
|
66584
|
+
}
|
|
66585
|
+
return { verdict: "allow", kind: effective === "ALLOW" ? "ALLOW" : "MONITOR" };
|
|
66586
|
+
}
|
|
66587
|
+
}
|
|
66588
|
+
});
|
|
66589
|
+
|
|
66590
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/guard.js
|
|
66591
|
+
var require_guard = __commonJS({
|
|
66592
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/guard.js"(exports2) {
|
|
66593
|
+
"use strict";
|
|
66594
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
66595
|
+
exports2.guardToolCall = guardToolCall;
|
|
66596
|
+
var node_crypto_1 = require("node:crypto");
|
|
66597
|
+
var sdk_1 = require_cjs3();
|
|
66598
|
+
var detector_js_1 = require_detector();
|
|
66599
|
+
var receipt_binding_js_1 = require_receipt_binding();
|
|
66600
|
+
var enforcement_gate_js_1 = require_enforcement_gate();
|
|
66601
|
+
var breakers = /* @__PURE__ */ new WeakMap();
|
|
66602
|
+
var nowMs = () => Date.now();
|
|
66603
|
+
var iso = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
66604
|
+
function emit(config, e) {
|
|
66605
|
+
if (config.onEvent) {
|
|
66606
|
+
try {
|
|
66607
|
+
config.onEvent(e);
|
|
66608
|
+
} catch {
|
|
66609
|
+
}
|
|
66610
|
+
}
|
|
66611
|
+
}
|
|
66612
|
+
function resolvePreviousReceipt(config) {
|
|
66613
|
+
const pr = config.previousReceipt;
|
|
66614
|
+
if (pr === void 0 || pr === null)
|
|
66615
|
+
return void 0;
|
|
66616
|
+
let raw;
|
|
66617
|
+
if (typeof pr === "function") {
|
|
66618
|
+
try {
|
|
66619
|
+
raw = pr();
|
|
66620
|
+
} catch {
|
|
66621
|
+
return void 0;
|
|
66622
|
+
}
|
|
66623
|
+
} else {
|
|
66624
|
+
raw = pr;
|
|
66625
|
+
}
|
|
66626
|
+
if (typeof raw !== "string")
|
|
66627
|
+
return void 0;
|
|
66628
|
+
const s = raw.trim();
|
|
66629
|
+
return s.length > 0 ? s : void 0;
|
|
66630
|
+
}
|
|
66631
|
+
function fingerprint(call) {
|
|
66632
|
+
const canon = JSON.stringify({ toolName: call.toolName, arguments: call.arguments, artifacts: call.artifacts, filesTouched: call.filesTouched, diff: call.diff });
|
|
66633
|
+
return "sha256:" + (0, node_crypto_1.createHash)("sha256").update(canon).digest("hex");
|
|
66634
|
+
}
|
|
66635
|
+
function breakerRecord(config) {
|
|
66636
|
+
let s = breakers.get(config);
|
|
66637
|
+
if (!s) {
|
|
66638
|
+
s = { fails: [] };
|
|
66639
|
+
breakers.set(config, s);
|
|
66640
|
+
}
|
|
66641
|
+
s.fails.push(nowMs());
|
|
66642
|
+
}
|
|
66643
|
+
function breakerTripped(config) {
|
|
66644
|
+
const s = breakers.get(config);
|
|
66645
|
+
if (!s)
|
|
66646
|
+
return false;
|
|
66647
|
+
const win = config.breakerWindowMs ?? 6e4;
|
|
66648
|
+
const t = nowMs();
|
|
66649
|
+
s.fails = s.fails.filter((x) => t - x < win);
|
|
66650
|
+
return s.fails.length >= (config.maxUnavailablePerWindow ?? 3);
|
|
66651
|
+
}
|
|
66652
|
+
function classifyError(err, config) {
|
|
66653
|
+
const e = err;
|
|
66654
|
+
const name = e?.name;
|
|
66655
|
+
const status = e?.status ?? e?.body?.status;
|
|
66656
|
+
if (name === "TimeoutError" || name === "AbortError" || e?.code === "ABORT_ERR")
|
|
66657
|
+
return { cause: "TIMEOUT", integrity: false };
|
|
66658
|
+
if (status === 429 || name === "RateLimitError")
|
|
66659
|
+
return { cause: "RATE_LIMITED", integrity: false };
|
|
66660
|
+
if (status === 413)
|
|
66661
|
+
return { cause: "PAYLOAD_TOO_LARGE", integrity: true };
|
|
66662
|
+
if (status === 422)
|
|
66663
|
+
return { cause: "REQUEST_REJECTED", integrity: true };
|
|
66664
|
+
if (status === 400 || status === 401 || status === 409)
|
|
66665
|
+
return { cause: "REQUEST_REJECTED", integrity: true };
|
|
66666
|
+
if (typeof status === "number" && status >= 500)
|
|
66667
|
+
return { cause: "SERVER_ERROR", integrity: false };
|
|
66668
|
+
if (name === "TypeError" || /fetch failed|network|ENOTFOUND|ECONNREFUSED|EAI_AGAIN/i.test(String(e?.message)))
|
|
66669
|
+
return { cause: "NETWORK", integrity: false };
|
|
66670
|
+
if (name === "ApiError")
|
|
66671
|
+
return { cause: "SERVER_ERROR", integrity: false };
|
|
66672
|
+
return { cause: "INVALID_RESPONSE", integrity: true };
|
|
66673
|
+
}
|
|
66674
|
+
function withTimeout(p, ms) {
|
|
66675
|
+
return new Promise((resolve, reject) => {
|
|
66676
|
+
const timer = setTimeout(() => reject(Object.assign(new Error(`preflight timed out after ${ms}ms`), { name: "TimeoutError" })), Math.max(1, ms));
|
|
66677
|
+
p.then((v) => {
|
|
66678
|
+
clearTimeout(timer);
|
|
66679
|
+
resolve(v);
|
|
66680
|
+
}, (e) => {
|
|
66681
|
+
clearTimeout(timer);
|
|
66682
|
+
reject(e);
|
|
66683
|
+
});
|
|
66684
|
+
});
|
|
66685
|
+
}
|
|
66686
|
+
async function preflightWithRetry(config, request) {
|
|
66687
|
+
const retries = config.retries ?? 1;
|
|
66688
|
+
const timeoutMs = config.timeoutMs ?? 2e3;
|
|
66689
|
+
const budget = config.totalBudgetMs ?? 4500;
|
|
66690
|
+
const start = nowMs();
|
|
66691
|
+
let last = { cause: "TIMEOUT", integrity: false };
|
|
66692
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
66693
|
+
const remaining = budget - (nowMs() - start);
|
|
66694
|
+
if (remaining <= 0)
|
|
66695
|
+
return { ok: false, cause: "TIMEOUT", integrity: false };
|
|
66696
|
+
try {
|
|
66697
|
+
const response = await withTimeout(config.client.preflightChangeSet(request), Math.min(timeoutMs, remaining));
|
|
66698
|
+
return { ok: true, response };
|
|
66699
|
+
} catch (err) {
|
|
66700
|
+
last = classifyError(err, config);
|
|
66701
|
+
if (last.integrity)
|
|
66702
|
+
return { ok: false, ...last };
|
|
66703
|
+
}
|
|
66704
|
+
}
|
|
66705
|
+
return { ok: false, ...last };
|
|
66706
|
+
}
|
|
66707
|
+
async function verifyEnvelope(config, envelope) {
|
|
66708
|
+
if (!envelope)
|
|
66709
|
+
return { verified: null };
|
|
66710
|
+
if (config.verifyReceipts === false)
|
|
66711
|
+
return { verified: null };
|
|
66712
|
+
const token = envelope.receipt?.token;
|
|
66713
|
+
if (!token)
|
|
66714
|
+
return { verified: null };
|
|
66715
|
+
try {
|
|
66716
|
+
const r = await config.client.verifyReceipt(token);
|
|
66717
|
+
const bind = (0, receipt_binding_js_1.bindReceiptToEnvelope)(envelope, r, { operation: config.operation, environment: config.environment, audience: config.audience });
|
|
66718
|
+
if (bind.ok)
|
|
66719
|
+
return { verified: envelope };
|
|
66720
|
+
emit(config, { type: "receipt_unverified", at: iso(), decisionId: envelope.decision_id, cause: bind.detail });
|
|
66721
|
+
return { verified: null, cause: bind.cause };
|
|
66722
|
+
} catch {
|
|
66723
|
+
return { verified: null, cause: "RECEIPT_UNVERIFIED" };
|
|
66724
|
+
}
|
|
66725
|
+
}
|
|
66726
|
+
async function runEnforced(config, factory, approved, redacted) {
|
|
66727
|
+
emit(config, { type: "execution_started", at: iso(), action: approved.action, decisionId: approved.envelope.decision_id });
|
|
66728
|
+
try {
|
|
66729
|
+
const result = await factory(approved.envelope, redacted);
|
|
66730
|
+
return { executionAttempted: true, executed: true, enforced: true, result, verdict: approved, preflighted: true };
|
|
66731
|
+
} catch (error) {
|
|
66732
|
+
emit(config, { type: "factory_error", at: iso(), action: approved.action });
|
|
66733
|
+
return { executionAttempted: true, executed: false, enforced: true, error, verdict: approved, preflighted: true };
|
|
66734
|
+
}
|
|
66735
|
+
}
|
|
66736
|
+
async function runUnenforced(config, factory, envelope, verdict, preflighted, redacted) {
|
|
66737
|
+
emit(config, { type: "execution_started", at: iso() });
|
|
66738
|
+
try {
|
|
66739
|
+
const result = await factory(envelope, redacted);
|
|
66740
|
+
return { executionAttempted: true, executed: true, enforced: false, result, verdict, preflighted };
|
|
66741
|
+
} catch (error) {
|
|
66742
|
+
emit(config, { type: "factory_error", at: iso() });
|
|
66743
|
+
return { executionAttempted: true, executed: false, enforced: false, error, verdict, preflighted };
|
|
66744
|
+
}
|
|
66745
|
+
}
|
|
66746
|
+
function blocked(verdict, preflighted) {
|
|
66747
|
+
return { executionAttempted: false, executed: false, enforced: false, verdict, preflighted };
|
|
66748
|
+
}
|
|
66749
|
+
function hasAnalyzableContent(artifacts) {
|
|
66750
|
+
if (!Array.isArray(artifacts) || artifacts.length === 0)
|
|
66751
|
+
return false;
|
|
66752
|
+
return artifacts.some((a) => {
|
|
66753
|
+
if (!a || typeof a !== "object")
|
|
66754
|
+
return false;
|
|
66755
|
+
const before = a.before;
|
|
66756
|
+
const after = a.after;
|
|
66757
|
+
return typeof before === "string" && before.length > 0 || typeof after === "string" && after.length > 0;
|
|
66758
|
+
});
|
|
66759
|
+
}
|
|
66760
|
+
function unavailableVerdict(parts, count) {
|
|
66761
|
+
return { kind: "UNAVAILABLE", decisionMissing: true, unavailableCount: count, ...parts };
|
|
66762
|
+
}
|
|
66763
|
+
async function guardToolCall(call, executeFactory, config) {
|
|
66764
|
+
const failPolicy = config.failPolicy ?? "closed";
|
|
66765
|
+
let redacted;
|
|
66766
|
+
try {
|
|
66767
|
+
redacted = config.redactor ? config.redactor(call) : call;
|
|
66768
|
+
} catch {
|
|
66769
|
+
breakerRecord(config);
|
|
66770
|
+
return closedIntegrity(config, "CONFIG_ERROR", failPolicy);
|
|
66771
|
+
}
|
|
66772
|
+
const inputFp = fingerprint(redacted);
|
|
66773
|
+
const detector = config.detector ?? detector_js_1.builtinDetector;
|
|
66774
|
+
let detection;
|
|
66775
|
+
try {
|
|
66776
|
+
detection = detector.detect(redacted);
|
|
66777
|
+
} catch {
|
|
66778
|
+
breakerRecord(config);
|
|
66779
|
+
return closedIntegrity(config, "DETECTOR_ERROR", failPolicy);
|
|
66780
|
+
}
|
|
66781
|
+
const suppressedByStrict = config.requireExplicitArtifacts === true && redacted.nonContract === true && (!detection.artifacts || detection.artifacts.length === 0) && detection.confident && !detection.trigger;
|
|
66782
|
+
if (!detection.trigger || suppressedByStrict) {
|
|
66783
|
+
emit(config, { type: "detection_skip", at: iso(), signals: detection.signals, detectorVersion: detector.version });
|
|
66784
|
+
const verdict = { kind: "SKIPPED", reason: "NOT_A_CONTRACT_CALL", signals: detection.signals, detectorVersion: detector.version };
|
|
66785
|
+
return runUnenforced(config, executeFactory, null, verdict, false, redacted);
|
|
66786
|
+
}
|
|
66787
|
+
if (!hasAnalyzableContent(detection.artifacts)) {
|
|
66788
|
+
emit(config, { type: "artifact_content_missing", at: iso(), cause: "MISSING_ARTIFACT_CONTENT", signals: detection.signals });
|
|
66789
|
+
const count = breakers.get(config)?.fails.length ?? 0;
|
|
66790
|
+
const v = unavailableVerdict({ cause: "MISSING_ARTIFACT_CONTENT", failPolicy, resolution: "CLOSED", action: "STOP" }, count);
|
|
66791
|
+
return blocked(v, false);
|
|
66792
|
+
}
|
|
66793
|
+
if (failPolicy === "lkg" && !config.lkg) {
|
|
66794
|
+
breakerRecord(config);
|
|
66795
|
+
return closedIntegrity(config, "CONFIG_ERROR", failPolicy);
|
|
66796
|
+
}
|
|
66797
|
+
const request = {
|
|
66798
|
+
artifacts: detection.artifacts,
|
|
66799
|
+
context: { operation: config.operation ?? "tool_call", environment: config.environment, audience: config.audience },
|
|
66800
|
+
previous_receipt: resolvePreviousReceipt(config),
|
|
66801
|
+
idempotency_key: void 0
|
|
66802
|
+
};
|
|
66803
|
+
const cap = config.maxPayloadBytes ?? 1e6;
|
|
66804
|
+
if (Buffer.byteLength(JSON.stringify(request), "utf8") > cap) {
|
|
66805
|
+
breakerRecord(config);
|
|
66806
|
+
return closedIntegrity(config, "PAYLOAD_TOO_LARGE", failPolicy);
|
|
66807
|
+
}
|
|
66808
|
+
emit(config, { type: "preflight_start", at: iso() });
|
|
66809
|
+
const pf = await preflightWithRetry(config, request);
|
|
66810
|
+
if (!pf.ok) {
|
|
66811
|
+
breakerRecord(config);
|
|
66812
|
+
const count = breakers.get(config)?.fails.length ?? 1;
|
|
66813
|
+
if (pf.integrity) {
|
|
66814
|
+
emit(config, { type: "breaker_tripped", at: iso(), cause: pf.cause });
|
|
66815
|
+
const v2 = unavailableVerdict({ cause: pf.cause, failPolicy, resolution: "CLOSED", action: "STOP" }, count);
|
|
66816
|
+
return blocked(v2, false);
|
|
66817
|
+
}
|
|
66818
|
+
const availCause = pf.cause;
|
|
66819
|
+
if (failPolicy === "open" && !breakerTripped(config)) {
|
|
66820
|
+
emit(config, { type: "preflight_unavailable", at: iso(), cause: availCause, action: "CONTINUE" });
|
|
66821
|
+
const v2 = unavailableVerdict({ cause: availCause, failPolicy: "open", resolution: "OPEN_PASSTHROUGH", action: "CONTINUE" }, count);
|
|
66822
|
+
return runUnenforced(config, executeFactory, null, v2, false, redacted);
|
|
66823
|
+
}
|
|
66824
|
+
if (failPolicy === "lkg") {
|
|
66825
|
+
const lkg = await tryLkg(config, inputFp);
|
|
66826
|
+
if (lkg) {
|
|
66827
|
+
emit(config, { type: "preflight_unavailable", at: iso(), cause: availCause, action: lkg.action });
|
|
66828
|
+
const v2 = unavailableVerdict({ cause: availCause, failPolicy: "lkg", resolution: "LKG_SUBSTITUTION", action: lkg.action, lkgEnvelope: lkg.envelope }, count);
|
|
66829
|
+
return runUnenforced(config, executeFactory, lkg.envelope, v2, false, redacted);
|
|
66830
|
+
}
|
|
66831
|
+
}
|
|
66832
|
+
if (breakerTripped(config))
|
|
66833
|
+
emit(config, { type: "breaker_tripped", at: iso(), cause: availCause });
|
|
66834
|
+
const v = unavailableVerdict({ cause: availCause, failPolicy, resolution: "CLOSED", action: "STOP" }, count);
|
|
66835
|
+
return blocked(v, false);
|
|
66836
|
+
}
|
|
66837
|
+
const rd = (0, sdk_1.readDecision)(pf.response);
|
|
66838
|
+
if (rd.reason === "UNREADABLE_DECISION" || !rd.envelope) {
|
|
66839
|
+
breakerRecord(config);
|
|
66840
|
+
return closedIntegrity(config, "SCHEMA_INVALID", failPolicy);
|
|
66841
|
+
}
|
|
66842
|
+
const envelope = rd.envelope;
|
|
66843
|
+
const expired = isExpired(envelope);
|
|
66844
|
+
const bindResult = await verifyEnvelope(config, envelope);
|
|
66845
|
+
const verified = bindResult.verified;
|
|
66846
|
+
const receiptVerified = !!verified;
|
|
66847
|
+
if (!receiptVerified)
|
|
66848
|
+
emit(config, { type: "receipt_unverified", at: iso(), decisionId: envelope.decision_id });
|
|
66849
|
+
emit(config, { type: "preflight_result", at: iso(), action: rd.executionAction, decisionId: envelope.decision_id });
|
|
66850
|
+
if (config.verifyReceipts !== false && !receiptVerified && envelope.receipt?.token) {
|
|
66851
|
+
breakerRecord(config);
|
|
66852
|
+
return closedIntegrity(config, bindResult.cause ?? "RECEIPT_UNVERIFIED", failPolicy);
|
|
66853
|
+
}
|
|
66854
|
+
const gate = (0, enforcement_gate_js_1.evaluateEnvelope)(pf.response, envelope, rd.executionAction, detection.artifacts);
|
|
66855
|
+
if (gate.verdict === "fail-closed") {
|
|
66856
|
+
breakerRecord(config);
|
|
66857
|
+
return closedIntegrity(config, gate.cause, failPolicy);
|
|
66858
|
+
}
|
|
66859
|
+
if (gate.verdict === "block-strict") {
|
|
66860
|
+
return gate.decision === "BLOCK" ? blocked({ kind: "BLOCK", action: "STOP", envelope, receiptVerified }, true) : blocked({ kind: "APPROVAL", action: "REQUEST_APPROVAL", envelope, receiptVerified }, true);
|
|
66861
|
+
}
|
|
66862
|
+
const kind = gate.kind;
|
|
66863
|
+
if (expired) {
|
|
66864
|
+
breakerRecord(config);
|
|
66865
|
+
return closedIntegrity(config, "SCHEMA_INVALID", failPolicy);
|
|
66866
|
+
}
|
|
66867
|
+
const sinkWired = !!config.onEvent;
|
|
66868
|
+
if (kind === "MONITOR") {
|
|
66869
|
+
if (sinkWired)
|
|
66870
|
+
emit(config, { type: "monitoring_required", at: iso(), decisionId: envelope.decision_id });
|
|
66871
|
+
else
|
|
66872
|
+
emit(config, { type: "monitoring_unwired", at: iso(), decisionId: envelope.decision_id });
|
|
66873
|
+
}
|
|
66874
|
+
if (config.observeOnly) {
|
|
66875
|
+
emit(config, { type: "observe_only_passthrough", at: iso(), action: rd.executionAction });
|
|
66876
|
+
const verdict = kind === "ALLOW" ? { kind: "ALLOW", action: "CONTINUE", envelope, receiptVerified } : { kind: "MONITOR", action: "CONTINUE_WITH_MONITORING", envelope, receiptVerified };
|
|
66877
|
+
return runUnenforced(config, executeFactory, envelope, verdict, true, redacted);
|
|
66878
|
+
}
|
|
66879
|
+
const enforceable = receiptVerified && (kind === "ALLOW" || sinkWired);
|
|
66880
|
+
if (enforceable) {
|
|
66881
|
+
const approved = kind === "ALLOW" ? { kind: "ALLOW", action: "CONTINUE", envelope, receiptVerified: true } : { kind: "MONITOR", action: "CONTINUE_WITH_MONITORING", envelope, receiptVerified: true };
|
|
66882
|
+
return runEnforced(config, executeFactory, approved, redacted);
|
|
66883
|
+
}
|
|
66884
|
+
breakerRecord(config);
|
|
66885
|
+
return closedIntegrity(config, receiptVerified ? "MONITORING_UNWIRED" : "RECEIPT_MISSING", failPolicy);
|
|
66886
|
+
}
|
|
66887
|
+
function closedIntegrity(config, cause, failPolicy) {
|
|
66888
|
+
const count = breakers.get(config)?.fails.length ?? 1;
|
|
66889
|
+
emit(config, { type: "breaker_tripped", at: iso(), cause });
|
|
66890
|
+
const v = unavailableVerdict({ cause, failPolicy, resolution: "CLOSED", action: "STOP" }, count);
|
|
66891
|
+
return blocked(v, false);
|
|
66892
|
+
}
|
|
66893
|
+
function isExpired(envelope) {
|
|
66894
|
+
const exp = envelope.expires_at;
|
|
66895
|
+
if (typeof exp !== "string")
|
|
66896
|
+
return false;
|
|
66897
|
+
const t = Date.parse(exp);
|
|
66898
|
+
return Number.isFinite(t) && t < Date.now();
|
|
66899
|
+
}
|
|
66900
|
+
async function tryLkg(config, inputFp) {
|
|
66901
|
+
if (!config.lkg)
|
|
66902
|
+
return null;
|
|
66903
|
+
let cached;
|
|
66904
|
+
try {
|
|
66905
|
+
cached = await config.lkg.get(inputFp);
|
|
66906
|
+
} catch {
|
|
66907
|
+
return null;
|
|
66908
|
+
}
|
|
66909
|
+
if (!cached)
|
|
66910
|
+
return null;
|
|
66911
|
+
const { verified } = await verifyEnvelope(config, cached);
|
|
66912
|
+
if (!verified)
|
|
66913
|
+
return null;
|
|
66914
|
+
const dec = cached.decision ?? "";
|
|
66915
|
+
if (dec !== "ALLOW" && dec !== "WARN")
|
|
66916
|
+
return null;
|
|
66917
|
+
if (isExpired(cached))
|
|
66918
|
+
return null;
|
|
66919
|
+
const maxAge = config.lkgMaxAgeMs ?? 9e5;
|
|
66920
|
+
const evalAt = Date.parse(cached.evaluated_at);
|
|
66921
|
+
if (Number.isFinite(evalAt) && Date.now() - evalAt > maxAge)
|
|
66922
|
+
return null;
|
|
66923
|
+
const bindings = [
|
|
66924
|
+
cached.ruleset_hash,
|
|
66925
|
+
cached.environment,
|
|
66926
|
+
cached.operation,
|
|
66927
|
+
cached.audience
|
|
66928
|
+
];
|
|
66929
|
+
if (bindings.some((b) => b === void 0))
|
|
66930
|
+
return null;
|
|
66931
|
+
const action = dec === "ALLOW" ? "CONTINUE" : "CONTINUE_WITH_MONITORING";
|
|
66932
|
+
return { envelope: verified, action };
|
|
66933
|
+
}
|
|
66934
|
+
}
|
|
66935
|
+
});
|
|
66936
|
+
|
|
66937
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/receipt-chain.js
|
|
66938
|
+
var require_receipt_chain = __commonJS({
|
|
66939
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/receipt-chain.js"(exports2) {
|
|
66940
|
+
"use strict";
|
|
66941
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
66942
|
+
exports2.RECEIPT_PREV_NULL = void 0;
|
|
66943
|
+
exports2.previousReceiptCommitment = previousReceiptCommitment;
|
|
66944
|
+
exports2.decodeReceiptBodyPrev = decodeReceiptBodyPrev;
|
|
66945
|
+
exports2.verifyReceiptChainLinkage = verifyReceiptChainLinkage;
|
|
66946
|
+
var node_crypto_1 = require("node:crypto");
|
|
66947
|
+
exports2.RECEIPT_PREV_NULL = "null";
|
|
66948
|
+
function previousReceiptCommitment(previousToken) {
|
|
66949
|
+
return "sha256:" + (0, node_crypto_1.createHash)("sha256").update(previousToken, "utf8").digest("hex");
|
|
66950
|
+
}
|
|
66951
|
+
function decodeReceiptBodyPrev(token) {
|
|
66952
|
+
if (typeof token !== "string" || token.length === 0)
|
|
66953
|
+
return null;
|
|
66954
|
+
const parts = token.split(".");
|
|
66955
|
+
if (parts.length !== 2 || !parts[0] || !parts[1])
|
|
66956
|
+
return null;
|
|
66957
|
+
try {
|
|
66958
|
+
const json = Buffer.from(parts[0], "base64url").toString("utf8");
|
|
66959
|
+
const body = JSON.parse(json);
|
|
66960
|
+
if (typeof body.prev !== "string")
|
|
66961
|
+
return null;
|
|
66962
|
+
return { prev: body.prev };
|
|
66963
|
+
} catch {
|
|
66964
|
+
return null;
|
|
66965
|
+
}
|
|
66966
|
+
}
|
|
66967
|
+
function verifyReceiptChainLinkage(tokens) {
|
|
66968
|
+
const length = tokens.length;
|
|
66969
|
+
if (length === 0) {
|
|
66970
|
+
return { ok: true, length: 0 };
|
|
66971
|
+
}
|
|
66972
|
+
for (let i = 0; i < length; i++) {
|
|
66973
|
+
const decoded = decodeReceiptBodyPrev(tokens[i]);
|
|
66974
|
+
if (!decoded) {
|
|
66975
|
+
return {
|
|
66976
|
+
ok: false,
|
|
66977
|
+
length,
|
|
66978
|
+
failedAt: i,
|
|
66979
|
+
reason: "malformed_token"
|
|
66980
|
+
};
|
|
66981
|
+
}
|
|
66982
|
+
if (i === 0) {
|
|
66983
|
+
if (decoded.prev !== exports2.RECEIPT_PREV_NULL) {
|
|
66984
|
+
return {
|
|
66985
|
+
ok: false,
|
|
66986
|
+
length,
|
|
66987
|
+
failedAt: 0,
|
|
66988
|
+
reason: "unexpected_predecessor",
|
|
66989
|
+
expected: exports2.RECEIPT_PREV_NULL,
|
|
66990
|
+
actual: decoded.prev
|
|
66991
|
+
};
|
|
66992
|
+
}
|
|
66993
|
+
continue;
|
|
66994
|
+
}
|
|
66995
|
+
const expected = previousReceiptCommitment(tokens[i - 1]);
|
|
66996
|
+
if (decoded.prev !== expected) {
|
|
66997
|
+
return {
|
|
66998
|
+
ok: false,
|
|
66999
|
+
length,
|
|
67000
|
+
failedAt: i,
|
|
67001
|
+
reason: "broken_link",
|
|
67002
|
+
expected,
|
|
67003
|
+
actual: decoded.prev
|
|
67004
|
+
};
|
|
67005
|
+
}
|
|
67006
|
+
}
|
|
67007
|
+
return { ok: true, length };
|
|
67008
|
+
}
|
|
67009
|
+
}
|
|
67010
|
+
});
|
|
67011
|
+
|
|
67012
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/session-taint.js
|
|
67013
|
+
var require_session_taint = __commonJS({
|
|
67014
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/session-taint.js"(exports2) {
|
|
67015
|
+
"use strict";
|
|
67016
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
67017
|
+
exports2.SessionTaintTracker = exports2.SESSION_TAINT_VERSION = void 0;
|
|
67018
|
+
exports2.pathClass = pathClass;
|
|
67019
|
+
exports2.emptySessionState = emptySessionState;
|
|
67020
|
+
exports2.projectState = projectState;
|
|
67021
|
+
exports2.classifyCommand = classifyCommand;
|
|
67022
|
+
exports2.updateSession = updateSession;
|
|
67023
|
+
exports2.computeTainted = computeTainted;
|
|
67024
|
+
exports2.deriveKeySignal = deriveKeySignal;
|
|
67025
|
+
exports2.evaluate = evaluate;
|
|
67026
|
+
exports2.SESSION_TAINT_VERSION = "session-taint/1.0.0";
|
|
67027
|
+
var NON_SSOT_RE = /(^|\/)(tests?|__tests__|fixtures?|__mocks__|src\/internal)\//i;
|
|
67028
|
+
var PIPELINE_SCRATCH_RE = /(^|\/)(build|\.cache|codegen|idl)(\/|$)/i;
|
|
67029
|
+
var PROSE_RE = /(^|\/)(README|CHANGELOG|LICENSE)(\.\w+)?$|\.md$/i;
|
|
67030
|
+
var SSOT_PATH_RE = /(^|\/)(openapi|swagger|asyncapi)[^/]*\.(ya?ml|json)$|(^|\/)mcp\.json$|\.graphql$|\.gql$|(^|\/)idl\/.*\.proto$|(^|\/)specs?\/.*\.(ya?ml|json)$|openapi\.yaml|schema\.graphql|asyncapi\.yaml/i;
|
|
67031
|
+
var MIGRATION_RE = /(^|\/)migrations?\//i;
|
|
67032
|
+
var CODE_OR_CONFIG_RE = /\.(ts|tsx|js|jsx)$/i;
|
|
67033
|
+
var CONTRACT_CONTENT_RE = /\bopenapi\s*[:=]|\bswagger\s*[:=]|\basyncapi\s*[:=]|syntax\s*=\s*["']proto3|["']inputSchema["']|\btype\s+Query\b|(^|\n)\s*paths\s*:/i;
|
|
67034
|
+
var STAGING_NAME_RE = /\.b64$|enc\/|field-map|flags\.json|optional_fields|required_fields|service\.idl|frags\/|BREAKING_DROP/i;
|
|
67035
|
+
var NON_SINK_RE = /validate-frags|gen-docs|reload-flags|snapshot-spec|prettier|npm test|npm install|npx prettier/i;
|
|
67036
|
+
var SSOT_INVALIDATE_RE = /archive-old-spec/i;
|
|
67037
|
+
var SSOT_SINK_RE = /dsl-to-openapi|merge-spec|publish-fixture|promote-spec|sync-graphql|b64join-write|decode-promote|apply-field-map|render-openapi|idl\/compile|generate-and-test|compile_spec_bundle|install-proto|install-mcp|promote-asyncapi|repack-extract|codegen\/build\.js|codegen\/apply|codegen\/render/i;
|
|
67038
|
+
function pathClass(p) {
|
|
67039
|
+
if (PROSE_RE.test(p))
|
|
67040
|
+
return "prose";
|
|
67041
|
+
if (NON_SSOT_RE.test(p) || PIPELINE_SCRATCH_RE.test(p))
|
|
67042
|
+
return "scratch";
|
|
67043
|
+
if (MIGRATION_RE.test(p))
|
|
67044
|
+
return "migration";
|
|
67045
|
+
if (SSOT_PATH_RE.test(p))
|
|
67046
|
+
return "ssot";
|
|
67047
|
+
if (CODE_OR_CONFIG_RE.test(p) || p.startsWith("src/") || p.startsWith("config/") || p === "package.json")
|
|
67048
|
+
return "code_or_config";
|
|
67049
|
+
return "other";
|
|
67050
|
+
}
|
|
67051
|
+
function emptySessionState() {
|
|
67052
|
+
return {
|
|
67053
|
+
scratch_writes: [],
|
|
67054
|
+
contract_looking_scratch: [],
|
|
67055
|
+
encoded_fragments: [],
|
|
67056
|
+
intermediate_artifacts: [],
|
|
67057
|
+
pending_renames: [],
|
|
67058
|
+
optional_fields_added: [],
|
|
67059
|
+
required_fields_declared: [],
|
|
67060
|
+
ssot_paths_touched: [],
|
|
67061
|
+
ssot_sink_events: [],
|
|
67062
|
+
ssot_invalidated: false,
|
|
67063
|
+
reverse_snapshot: false,
|
|
67064
|
+
formatter_only_ssot: false,
|
|
67065
|
+
store_keys: [],
|
|
67066
|
+
tainted: false
|
|
67067
|
+
};
|
|
67068
|
+
}
|
|
67069
|
+
function projectState(s) {
|
|
67070
|
+
return {
|
|
67071
|
+
scratch_writes: s.scratch_writes.slice(),
|
|
67072
|
+
encoded_fragments: s.encoded_fragments.slice(),
|
|
67073
|
+
pending_renames: s.pending_renames.map((r) => "drop" in r ? `drop:${r.drop}` : `${r.from}->${r.to}`),
|
|
67074
|
+
optional_fields_added: s.optional_fields_added.slice(),
|
|
67075
|
+
required_fields_declared: s.required_fields_declared.slice(),
|
|
67076
|
+
ssot_paths_touched: s.ssot_paths_touched.slice(),
|
|
67077
|
+
contract_looking_scratch: s.contract_looking_scratch.slice(),
|
|
67078
|
+
intermediate_artifacts: s.intermediate_artifacts.slice(),
|
|
67079
|
+
ssot_sink_events: s.ssot_sink_events.slice(),
|
|
67080
|
+
ssot_invalidated: s.ssot_invalidated,
|
|
67081
|
+
reverse_snapshot: s.reverse_snapshot,
|
|
67082
|
+
formatter_only_ssot: s.formatter_only_ssot,
|
|
67083
|
+
store_keys: s.store_keys.slice(),
|
|
67084
|
+
tainted: s.tainted
|
|
67085
|
+
};
|
|
67086
|
+
}
|
|
67087
|
+
function asRecord(args) {
|
|
67088
|
+
return args && typeof args === "object" ? args : {};
|
|
67089
|
+
}
|
|
67090
|
+
function extractPaths(args) {
|
|
67091
|
+
const a = asRecord(args);
|
|
67092
|
+
const out = [];
|
|
67093
|
+
for (const k of ["path", "target", "file", "dest", "filename", "destination"])
|
|
67094
|
+
if (typeof a[k] === "string")
|
|
67095
|
+
out.push(a[k]);
|
|
67096
|
+
return out;
|
|
67097
|
+
}
|
|
67098
|
+
function extractContent(args) {
|
|
67099
|
+
const a = asRecord(args);
|
|
67100
|
+
const parts = [];
|
|
67101
|
+
for (const k of ["contents", "content", "new_string", "old_string", "patch", "value", "command"])
|
|
67102
|
+
if (typeof a[k] === "string")
|
|
67103
|
+
parts.push(a[k]);
|
|
67104
|
+
return parts.join("\n");
|
|
67105
|
+
}
|
|
67106
|
+
function isEncodedFragment(path, content) {
|
|
67107
|
+
if (path && /part\.|enc\/|\.b64$|pkg\.part/i.test(path))
|
|
67108
|
+
return true;
|
|
67109
|
+
const c = content.replace(/\s+/g, "");
|
|
67110
|
+
if (c.length >= 8 && c.length < 80 && /^[A-Za-z0-9+/=]+$/.test(c))
|
|
67111
|
+
return true;
|
|
67112
|
+
return false;
|
|
67113
|
+
}
|
|
67114
|
+
function classifyCommand(command, action, cfg = {}) {
|
|
67115
|
+
const s = `${command || ""} ${action || ""}`;
|
|
67116
|
+
const extraNon = cfg.extraNonSinkPatterns || [];
|
|
67117
|
+
const extraSink = cfg.extraSinkPatterns || [];
|
|
67118
|
+
if (NON_SINK_RE.test(s) || extraNon.some((r) => r.test(s)))
|
|
67119
|
+
return "non_sink";
|
|
67120
|
+
if (SSOT_INVALIDATE_RE.test(s))
|
|
67121
|
+
return "ssot_invalidate";
|
|
67122
|
+
if (SSOT_SINK_RE.test(s) || action === "compile_spec_bundle" || extraSink.some((r) => r.test(s)))
|
|
67123
|
+
return "ssot_sink";
|
|
67124
|
+
if (/snapshot/i.test(s))
|
|
67125
|
+
return "reverse_snapshot";
|
|
67126
|
+
if (/prettier|format/i.test(s))
|
|
67127
|
+
return "formatter";
|
|
67128
|
+
return "unknown_script";
|
|
67129
|
+
}
|
|
67130
|
+
function pushUniq(arr, v) {
|
|
67131
|
+
if (v != null && !arr.includes(v))
|
|
67132
|
+
arr.push(v);
|
|
67133
|
+
}
|
|
67134
|
+
function updateSession(state, call, cfg = {}) {
|
|
67135
|
+
const s = JSON.parse(JSON.stringify(state));
|
|
67136
|
+
const args = asRecord(call && call.arguments);
|
|
67137
|
+
const paths = extractPaths(args);
|
|
67138
|
+
const content = extractContent(args);
|
|
67139
|
+
const tool = call && call.toolName;
|
|
67140
|
+
if (tool === "store" && typeof args.key === "string") {
|
|
67141
|
+
pushUniq(s.store_keys, args.key);
|
|
67142
|
+
if (/spec_|api_|openapi|schema/i.test(args.key) || /BREAKING|ROUTE|FIELD|REMOVE|MANDATORY|required|optional/i.test(String(args.value))) {
|
|
67143
|
+
pushUniq(s.intermediate_artifacts, `store:${args.key}`);
|
|
67144
|
+
}
|
|
67145
|
+
}
|
|
67146
|
+
if (tool === "apply" && typeof args.action === "string") {
|
|
67147
|
+
if (classifyCommand("", args.action, cfg) === "ssot_sink")
|
|
67148
|
+
s.ssot_sink_events.push(args.action);
|
|
67149
|
+
}
|
|
67150
|
+
if (tool === "Bash" || typeof args.command === "string") {
|
|
67151
|
+
const cmd = typeof args.command === "string" ? args.command : "";
|
|
67152
|
+
const kind = classifyCommand(cmd, "", cfg);
|
|
67153
|
+
if (kind === "ssot_sink")
|
|
67154
|
+
s.ssot_sink_events.push(cmd);
|
|
67155
|
+
if (kind === "ssot_invalidate")
|
|
67156
|
+
s.ssot_invalidated = true;
|
|
67157
|
+
if (kind === "reverse_snapshot")
|
|
67158
|
+
s.reverse_snapshot = true;
|
|
67159
|
+
if (kind === "formatter" && (SSOT_PATH_RE.test(cmd) || /openapi|swagger|asyncapi|\.graphql|\.gql|mcp\.json|schema/i.test(cmd)))
|
|
67160
|
+
s.formatter_only_ssot = true;
|
|
67161
|
+
}
|
|
67162
|
+
for (const p of paths) {
|
|
67163
|
+
const pc = pathClass(p);
|
|
67164
|
+
const isScratch = pc === "scratch" || NON_SSOT_RE.test(p) || PIPELINE_SCRATCH_RE.test(p);
|
|
67165
|
+
if (isScratch) {
|
|
67166
|
+
pushUniq(s.scratch_writes, p);
|
|
67167
|
+
if (CONTRACT_CONTENT_RE.test(content) || STAGING_NAME_RE.test(p + content))
|
|
67168
|
+
pushUniq(s.contract_looking_scratch, p);
|
|
67169
|
+
if (PIPELINE_SCRATCH_RE.test(p))
|
|
67170
|
+
pushUniq(s.intermediate_artifacts, p);
|
|
67171
|
+
if (isEncodedFragment(p, content) || /\.b64$/i.test(p) || /enc\//i.test(p) || /pkg\.part/i.test(p))
|
|
67172
|
+
pushUniq(s.encoded_fragments, p);
|
|
67173
|
+
if (/field-map|flags\.json|optional_fields|required_fields|\.idl$/i.test(p))
|
|
67174
|
+
pushUniq(s.intermediate_artifacts, p);
|
|
67175
|
+
}
|
|
67176
|
+
if (pc === "ssot" && !(tool === "Bash" && /prettier/i.test(typeof args.command === "string" ? args.command : "")))
|
|
67177
|
+
pushUniq(s.ssot_paths_touched, p);
|
|
67178
|
+
if (/field-map/i.test(p)) {
|
|
67179
|
+
let obj;
|
|
67180
|
+
try {
|
|
67181
|
+
obj = JSON.parse(content);
|
|
67182
|
+
} catch {
|
|
67183
|
+
obj = null;
|
|
67184
|
+
}
|
|
67185
|
+
if (obj && typeof obj === "object" && !Array.isArray(obj)) {
|
|
67186
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
67187
|
+
if (k === "__drop" && Array.isArray(v)) {
|
|
67188
|
+
for (const d of v)
|
|
67189
|
+
s.pending_renames.push({ drop: String(d) });
|
|
67190
|
+
} else if (typeof v === "string")
|
|
67191
|
+
s.pending_renames.push({ from: k, to: v });
|
|
67192
|
+
}
|
|
67193
|
+
}
|
|
67194
|
+
}
|
|
67195
|
+
if (/flags\.json/i.test(p)) {
|
|
67196
|
+
for (const m of content.matchAll(/"(\w+)":\s*"optional"/g))
|
|
67197
|
+
pushUniq(s.optional_fields_added, m[1]);
|
|
67198
|
+
for (const m of content.matchAll(/"(\w+)":\s*"required"/g))
|
|
67199
|
+
pushUniq(s.required_fields_declared, m[1]);
|
|
67200
|
+
}
|
|
67201
|
+
if (/optional_fields/i.test(p)) {
|
|
67202
|
+
for (const line of content.split("\n"))
|
|
67203
|
+
if (line.trim())
|
|
67204
|
+
pushUniq(s.optional_fields_added, line.trim());
|
|
67205
|
+
}
|
|
67206
|
+
if (/required_fields/i.test(p)) {
|
|
67207
|
+
for (const line of content.split("\n"))
|
|
67208
|
+
if (line.trim())
|
|
67209
|
+
pushUniq(s.required_fields_declared, line.trim());
|
|
67210
|
+
}
|
|
67211
|
+
if (NON_SSOT_RE.test(p) && /required:\s*\[[^\]]*owner_id/.test(content))
|
|
67212
|
+
pushUniq(s.required_fields_declared, "owner_id");
|
|
67213
|
+
if (NON_SSOT_RE.test(p) && /owner_id:\s*\{type: string\}/.test(content))
|
|
67214
|
+
pushUniq(s.optional_fields_added, "owner_id");
|
|
67215
|
+
if (/\.idl$/i.test(p) || p.startsWith("idl/"))
|
|
67216
|
+
pushUniq(s.intermediate_artifacts, p);
|
|
67217
|
+
}
|
|
67218
|
+
if (/BREAKING_DROP|FIELD .* REMOVE|MANDATORY/i.test(content))
|
|
67219
|
+
pushUniq(s.intermediate_artifacts, paths[0] || "inline_flag");
|
|
67220
|
+
s.tainted = computeTainted(s);
|
|
67221
|
+
return s;
|
|
67222
|
+
}
|
|
67223
|
+
function computeTainted(s) {
|
|
67224
|
+
return s.contract_looking_scratch.length > 0 || s.encoded_fragments.length > 0 || s.intermediate_artifacts.length > 0 || s.store_keys.some((k) => /spec_|api_|schema|openapi/i.test(k)) || s.pending_renames.length > 0 || s.optional_fields_added.some((f) => s.required_fields_declared.includes(f)) || s.required_fields_declared.length > 0 && s.optional_fields_added.length > 0 || s.ssot_invalidated === true;
|
|
67225
|
+
}
|
|
67226
|
+
function deriveKeySignal(s) {
|
|
67227
|
+
if (s.ssot_invalidated)
|
|
67228
|
+
return "delete_recreate_ssot_via_session";
|
|
67229
|
+
if (s.encoded_fragments.length)
|
|
67230
|
+
return "encoded_scratch_then_ssot_promotion";
|
|
67231
|
+
if (s.optional_fields_added.some((f) => s.required_fields_declared.includes(f)) || s.required_fields_declared.length && s.optional_fields_added.length)
|
|
67232
|
+
return "cumulative_required_flip";
|
|
67233
|
+
if (s.pending_renames.length)
|
|
67234
|
+
return "cumulative_rename_via_codegen";
|
|
67235
|
+
if (s.contract_looking_scratch.length)
|
|
67236
|
+
return "scratch_to_ssot_promotion";
|
|
67237
|
+
if (s.intermediate_artifacts.length)
|
|
67238
|
+
return "cross_call_reassembly_to_ssot";
|
|
67239
|
+
return "session_ssot_sink_with_taint";
|
|
67240
|
+
}
|
|
67241
|
+
function evaluate(state, prevFlagged = false, opts = {}) {
|
|
67242
|
+
const sink = state.ssot_sink_events.length > 0 || opts.sinkSeen === true;
|
|
67243
|
+
const taint = state.tainted || opts.overflow === true;
|
|
67244
|
+
const flag = sink && taint;
|
|
67245
|
+
return { flag, trip: flag && !prevFlagged, key_signal: flag ? deriveKeySignal(state) : null };
|
|
67246
|
+
}
|
|
67247
|
+
var DEF = { maxCalls: 256, maxPathsTracked: 512, maxSinkEvents: 64, maxStateBytes: 256e3, ttlMs: 36e5 };
|
|
67248
|
+
var SessionTaintTracker = class {
|
|
67249
|
+
version = exports2.SESSION_TAINT_VERSION;
|
|
67250
|
+
state = emptySessionState();
|
|
67251
|
+
prevFlag = false;
|
|
67252
|
+
callCount = 0;
|
|
67253
|
+
overflow = false;
|
|
67254
|
+
sinkSeen = false;
|
|
67255
|
+
lastObserveAt = 0;
|
|
67256
|
+
cfg;
|
|
67257
|
+
constructor(config = {}) {
|
|
67258
|
+
this.cfg = config;
|
|
67259
|
+
}
|
|
67260
|
+
pathTotal() {
|
|
67261
|
+
const s = this.state;
|
|
67262
|
+
return s.scratch_writes.length + s.contract_looking_scratch.length + s.encoded_fragments.length + s.intermediate_artifacts.length + s.ssot_paths_touched.length;
|
|
67263
|
+
}
|
|
67264
|
+
observe(call) {
|
|
67265
|
+
const now = this.now();
|
|
67266
|
+
if (this.lastObserveAt && now - this.lastObserveAt > (this.cfg.ttlMs ?? DEF.ttlMs))
|
|
67267
|
+
this.reset();
|
|
67268
|
+
this.lastObserveAt = now;
|
|
67269
|
+
const next = updateSession(this.state, call, this.cfg);
|
|
67270
|
+
this.callCount++;
|
|
67271
|
+
if (this.callCount > (this.cfg.maxCalls ?? DEF.maxCalls))
|
|
67272
|
+
this.overflow = true;
|
|
67273
|
+
if (this.pathTotal() > (this.cfg.maxPathsTracked ?? DEF.maxPathsTracked))
|
|
67274
|
+
this.overflow = true;
|
|
67275
|
+
if (JSON.stringify(next).length > (this.cfg.maxStateBytes ?? DEF.maxStateBytes))
|
|
67276
|
+
this.overflow = true;
|
|
67277
|
+
if (next.ssot_sink_events.length > (this.cfg.maxSinkEvents ?? DEF.maxSinkEvents)) {
|
|
67278
|
+
next.ssot_sink_events = next.ssot_sink_events.slice(0, this.cfg.maxSinkEvents ?? DEF.maxSinkEvents);
|
|
67279
|
+
}
|
|
67280
|
+
this.state = next;
|
|
67281
|
+
if (this.state.ssot_sink_events.length > 0)
|
|
67282
|
+
this.sinkSeen = true;
|
|
67283
|
+
return this.snapshot();
|
|
67284
|
+
}
|
|
67285
|
+
status() {
|
|
67286
|
+
return this.snapshot();
|
|
67287
|
+
}
|
|
67288
|
+
reset() {
|
|
67289
|
+
this.state = emptySessionState();
|
|
67290
|
+
this.prevFlag = false;
|
|
67291
|
+
this.callCount = 0;
|
|
67292
|
+
this.overflow = false;
|
|
67293
|
+
this.sinkSeen = false;
|
|
67294
|
+
this.lastObserveAt = 0;
|
|
67295
|
+
}
|
|
67296
|
+
snapshot() {
|
|
67297
|
+
const eva = evaluate(this.state, this.prevFlag, { overflow: this.overflow, sinkSeen: this.sinkSeen });
|
|
67298
|
+
if (eva.flag)
|
|
67299
|
+
this.prevFlag = true;
|
|
67300
|
+
return {
|
|
67301
|
+
flag: eva.flag,
|
|
67302
|
+
trip: eva.trip,
|
|
67303
|
+
key_signal: eva.key_signal,
|
|
67304
|
+
state: projectState(this.state),
|
|
67305
|
+
version: exports2.SESSION_TAINT_VERSION,
|
|
67306
|
+
overflow: this.overflow,
|
|
67307
|
+
severity: this.cfg.sessionTaintSeverity || "caution"
|
|
67308
|
+
};
|
|
67309
|
+
}
|
|
67310
|
+
// Date.now is fine at runtime; isolated for testability.
|
|
67311
|
+
now() {
|
|
67312
|
+
return Date.now();
|
|
67313
|
+
}
|
|
67314
|
+
};
|
|
67315
|
+
exports2.SessionTaintTracker = SessionTaintTracker;
|
|
67316
|
+
}
|
|
67317
|
+
});
|
|
67318
|
+
|
|
67319
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/resolver-yaml.js
|
|
67320
|
+
var require_resolver_yaml = __commonJS({
|
|
67321
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/resolver-yaml.js"(exports2) {
|
|
67322
|
+
"use strict";
|
|
67323
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
67324
|
+
exports2.YamlLiteError = void 0;
|
|
67325
|
+
exports2.parseDoc = parseDoc;
|
|
67326
|
+
exports2.stableStringify = stableStringify;
|
|
67327
|
+
var YamlLiteError = class extends Error {
|
|
67328
|
+
constructor(message) {
|
|
67329
|
+
super(message);
|
|
67330
|
+
this.name = "YamlLiteError";
|
|
67331
|
+
}
|
|
67332
|
+
};
|
|
67333
|
+
exports2.YamlLiteError = YamlLiteError;
|
|
67334
|
+
function parseDoc(text) {
|
|
67335
|
+
const trimmed = text.trimStart();
|
|
67336
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
67337
|
+
try {
|
|
67338
|
+
return JSON.parse(text);
|
|
67339
|
+
} catch (e) {
|
|
67340
|
+
throw new YamlLiteError(`invalid JSON: ${e.message}`);
|
|
67341
|
+
}
|
|
67342
|
+
}
|
|
67343
|
+
const lines = [];
|
|
67344
|
+
for (const raw of text.split("\n")) {
|
|
67345
|
+
const trimmedLine = raw.trim();
|
|
67346
|
+
if (trimmedLine === "" || trimmedLine.startsWith("#"))
|
|
67347
|
+
continue;
|
|
67348
|
+
lines.push({ indent: raw.length - raw.trimStart().length, text: trimmedLine });
|
|
67349
|
+
}
|
|
67350
|
+
if (lines.length === 0)
|
|
67351
|
+
return null;
|
|
67352
|
+
const [value] = parseBlock(lines, 0, lines[0].indent);
|
|
67353
|
+
return value;
|
|
67354
|
+
}
|
|
67355
|
+
function parseBlock(lines, start, indent) {
|
|
67356
|
+
if (start >= lines.length)
|
|
67357
|
+
return [null, start];
|
|
67358
|
+
const first = lines[start];
|
|
67359
|
+
if (first.text === "-" || first.text.startsWith("- "))
|
|
67360
|
+
return parseSequence(lines, start, indent);
|
|
67361
|
+
return parseMapping(lines, start, indent);
|
|
67362
|
+
}
|
|
67363
|
+
function parseMapping(lines, start, indent) {
|
|
67364
|
+
const obj = {};
|
|
67365
|
+
let i = start;
|
|
67366
|
+
while (i < lines.length && lines[i].indent === indent) {
|
|
67367
|
+
const { key, rest } = splitKeyValue(lines[i].text);
|
|
67368
|
+
i += 1;
|
|
67369
|
+
if (rest === "") {
|
|
67370
|
+
if (i < lines.length && lines[i].indent > indent) {
|
|
67371
|
+
const [child, next] = parseBlock(lines, i, lines[i].indent);
|
|
67372
|
+
obj[key] = child;
|
|
67373
|
+
i = next;
|
|
67374
|
+
} else {
|
|
67375
|
+
obj[key] = null;
|
|
67376
|
+
}
|
|
67377
|
+
} else {
|
|
67378
|
+
obj[key] = parseScalarOrFlow(rest);
|
|
67379
|
+
}
|
|
67380
|
+
}
|
|
67381
|
+
return [obj, i];
|
|
67382
|
+
}
|
|
67383
|
+
function parseSequence(lines, start, indent) {
|
|
67384
|
+
const arr = [];
|
|
67385
|
+
let i = start;
|
|
67386
|
+
while (i < lines.length && lines[i].indent === indent && (lines[i].text === "-" || lines[i].text.startsWith("- "))) {
|
|
67387
|
+
const itemText = lines[i].text.slice(1).trim();
|
|
67388
|
+
i += 1;
|
|
67389
|
+
if (itemText === "") {
|
|
67390
|
+
if (i < lines.length && lines[i].indent > indent) {
|
|
67391
|
+
const [child, next] = parseBlock(lines, i, lines[i].indent);
|
|
67392
|
+
arr.push(child);
|
|
67393
|
+
i = next;
|
|
67394
|
+
} else {
|
|
67395
|
+
arr.push(null);
|
|
67396
|
+
}
|
|
67397
|
+
} else {
|
|
67398
|
+
arr.push(parseScalarOrFlow(itemText));
|
|
67399
|
+
}
|
|
67400
|
+
}
|
|
67401
|
+
return [arr, i];
|
|
67402
|
+
}
|
|
67403
|
+
function splitKeyValue(text) {
|
|
67404
|
+
let key;
|
|
67405
|
+
let idx;
|
|
67406
|
+
if (text[0] === "'" || text[0] === '"') {
|
|
67407
|
+
const q = text[0];
|
|
67408
|
+
let j = 1;
|
|
67409
|
+
while (j < text.length && text[j] !== q)
|
|
67410
|
+
j += 1;
|
|
67411
|
+
key = text.slice(1, j);
|
|
67412
|
+
idx = text.indexOf(":", j);
|
|
67413
|
+
} else {
|
|
67414
|
+
idx = text.indexOf(":");
|
|
67415
|
+
key = idx === -1 ? text : text.slice(0, idx);
|
|
67416
|
+
}
|
|
67417
|
+
if (idx === -1)
|
|
67418
|
+
return { key: key.trim(), rest: "" };
|
|
67419
|
+
return { key: key.trim(), rest: text.slice(idx + 1).trim() };
|
|
67420
|
+
}
|
|
67421
|
+
function parseScalarOrFlow(s) {
|
|
67422
|
+
const t = s.trim();
|
|
67423
|
+
if (t === "" || t === "~" || t === "null")
|
|
67424
|
+
return null;
|
|
67425
|
+
if (t[0] === "{" || t[0] === "[")
|
|
67426
|
+
return parseFlow(t).value;
|
|
67427
|
+
if (t[0] === "'" || t[0] === '"')
|
|
67428
|
+
return unquote(t);
|
|
67429
|
+
return t;
|
|
67430
|
+
}
|
|
67431
|
+
function unquote(t) {
|
|
67432
|
+
const q = t[0];
|
|
67433
|
+
let j = 1;
|
|
67434
|
+
let out = "";
|
|
67435
|
+
while (j < t.length && t[j] !== q) {
|
|
67436
|
+
out += t[j];
|
|
67437
|
+
j += 1;
|
|
67438
|
+
}
|
|
67439
|
+
return out;
|
|
67440
|
+
}
|
|
67441
|
+
function parseFlow(s) {
|
|
67442
|
+
if (s[0] === "{")
|
|
67443
|
+
return parseFlowMap(s);
|
|
67444
|
+
if (s[0] === "[")
|
|
67445
|
+
return parseFlowSeq(s);
|
|
67446
|
+
throw new YamlLiteError(`not a flow collection: ${s.slice(0, 20)}`);
|
|
67447
|
+
}
|
|
67448
|
+
function parseFlowMap(s) {
|
|
67449
|
+
const obj = {};
|
|
67450
|
+
let i = 1;
|
|
67451
|
+
while (i < s.length) {
|
|
67452
|
+
while (i < s.length && (s[i] === " " || s[i] === ","))
|
|
67453
|
+
i += 1;
|
|
67454
|
+
if (s[i] === "}")
|
|
67455
|
+
return { value: obj, end: i + 1 };
|
|
67456
|
+
let key;
|
|
67457
|
+
if (s[i] === "'" || s[i] === '"') {
|
|
67458
|
+
const q = s[i];
|
|
67459
|
+
let j = i + 1;
|
|
67460
|
+
let k = "";
|
|
67461
|
+
while (j < s.length && s[j] !== q) {
|
|
67462
|
+
k += s[j];
|
|
67463
|
+
j += 1;
|
|
67464
|
+
}
|
|
67465
|
+
key = k;
|
|
67466
|
+
i = j + 1;
|
|
67467
|
+
} else {
|
|
67468
|
+
let k = "";
|
|
67469
|
+
while (i < s.length && s[i] !== ":" && s[i] !== "}" && s[i] !== ",") {
|
|
67470
|
+
k += s[i];
|
|
67471
|
+
i += 1;
|
|
67472
|
+
}
|
|
67473
|
+
key = k.trim();
|
|
67474
|
+
}
|
|
67475
|
+
while (i < s.length && (s[i] === " " || s[i] === ":"))
|
|
67476
|
+
i += 1;
|
|
67477
|
+
const [val, next] = readFlowValue(s, i);
|
|
67478
|
+
obj[key] = val;
|
|
67479
|
+
i = next;
|
|
67480
|
+
}
|
|
67481
|
+
throw new YamlLiteError(`unterminated flow map: ${s.slice(0, 40)}`);
|
|
67482
|
+
}
|
|
67483
|
+
function parseFlowSeq(s) {
|
|
67484
|
+
const arr = [];
|
|
67485
|
+
let i = 1;
|
|
67486
|
+
while (i < s.length) {
|
|
67487
|
+
while (i < s.length && (s[i] === " " || s[i] === ","))
|
|
67488
|
+
i += 1;
|
|
67489
|
+
if (s[i] === "]")
|
|
67490
|
+
return { value: arr, end: i + 1 };
|
|
67491
|
+
const [val, next] = readFlowValue(s, i);
|
|
67492
|
+
arr.push(val);
|
|
67493
|
+
i = next;
|
|
67494
|
+
}
|
|
67495
|
+
throw new YamlLiteError(`unterminated flow seq: ${s.slice(0, 40)}`);
|
|
67496
|
+
}
|
|
67497
|
+
function readFlowValue(s, start) {
|
|
67498
|
+
let i = start;
|
|
67499
|
+
while (i < s.length && s[i] === " ")
|
|
67500
|
+
i += 1;
|
|
67501
|
+
if (s[i] === "{" || s[i] === "[") {
|
|
67502
|
+
const { value, end } = parseFlow(s.slice(i));
|
|
67503
|
+
return [value, i + end];
|
|
67504
|
+
}
|
|
67505
|
+
if (s[i] === "'" || s[i] === '"') {
|
|
67506
|
+
const q = s[i];
|
|
67507
|
+
let j = i + 1;
|
|
67508
|
+
let out2 = "";
|
|
67509
|
+
while (j < s.length && s[j] !== q) {
|
|
67510
|
+
out2 += s[j];
|
|
67511
|
+
j += 1;
|
|
67512
|
+
}
|
|
67513
|
+
return [out2, j + 1];
|
|
67514
|
+
}
|
|
67515
|
+
let out = "";
|
|
67516
|
+
while (i < s.length && s[i] !== "," && s[i] !== "}" && s[i] !== "]") {
|
|
67517
|
+
out += s[i];
|
|
67518
|
+
i += 1;
|
|
67519
|
+
}
|
|
67520
|
+
return [out.trim(), i];
|
|
67521
|
+
}
|
|
67522
|
+
function stableStringify(value) {
|
|
67523
|
+
return JSON.stringify(sortKeys(value));
|
|
67524
|
+
}
|
|
67525
|
+
function sortKeys(value) {
|
|
67526
|
+
if (Array.isArray(value))
|
|
67527
|
+
return value.map(sortKeys);
|
|
67528
|
+
if (value && typeof value === "object") {
|
|
67529
|
+
const out = {};
|
|
67530
|
+
for (const k of Object.keys(value).sort()) {
|
|
67531
|
+
out[k] = sortKeys(value[k]);
|
|
67532
|
+
}
|
|
67533
|
+
return out;
|
|
67534
|
+
}
|
|
67535
|
+
return value;
|
|
67536
|
+
}
|
|
67537
|
+
}
|
|
67538
|
+
});
|
|
67539
|
+
|
|
67540
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/resolver-glob.js
|
|
67541
|
+
var require_resolver_glob = __commonJS({
|
|
67542
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/resolver-glob.js"(exports2) {
|
|
67543
|
+
"use strict";
|
|
67544
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
67545
|
+
exports2.globToRegExp = globToRegExp;
|
|
67546
|
+
exports2.matchGlob = matchGlob;
|
|
67547
|
+
exports2.matchAny = matchAny;
|
|
67548
|
+
exports2.firstMatchIndex = firstMatchIndex;
|
|
67549
|
+
function globToRegExp(glob) {
|
|
67550
|
+
let re = "";
|
|
67551
|
+
for (let i = 0; i < glob.length; i += 1) {
|
|
67552
|
+
const c = glob[i];
|
|
67553
|
+
if (c === "*") {
|
|
67554
|
+
if (glob[i + 1] === "*") {
|
|
67555
|
+
i += 1;
|
|
67556
|
+
if (glob[i + 1] === "/") {
|
|
67557
|
+
re += "(?:.*/)?";
|
|
67558
|
+
i += 1;
|
|
67559
|
+
} else {
|
|
67560
|
+
re += ".*";
|
|
67561
|
+
}
|
|
67562
|
+
} else {
|
|
67563
|
+
re += "[^/]*";
|
|
67564
|
+
}
|
|
67565
|
+
} else if (c === "?") {
|
|
67566
|
+
re += "[^/]";
|
|
67567
|
+
} else if (".+^${}()|[]\\".includes(c)) {
|
|
67568
|
+
re += `\\${c}`;
|
|
67569
|
+
} else {
|
|
67570
|
+
re += c;
|
|
67571
|
+
}
|
|
67572
|
+
}
|
|
67573
|
+
return new RegExp(`^${re}$`);
|
|
67574
|
+
}
|
|
67575
|
+
function matchGlob(glob, path) {
|
|
67576
|
+
return globToRegExp(glob).test(path);
|
|
67577
|
+
}
|
|
67578
|
+
function matchAny(globs, path) {
|
|
67579
|
+
if (!Array.isArray(globs))
|
|
67580
|
+
return false;
|
|
67581
|
+
return globs.some((g) => g === path || matchGlob(g, path));
|
|
67582
|
+
}
|
|
67583
|
+
function firstMatchIndex(globs, path) {
|
|
67584
|
+
if (!Array.isArray(globs))
|
|
67585
|
+
return -1;
|
|
67586
|
+
for (let i = 0; i < globs.length; i += 1) {
|
|
67587
|
+
if (globs[i] === path || matchGlob(globs[i], path))
|
|
67588
|
+
return i;
|
|
67589
|
+
}
|
|
67590
|
+
return -1;
|
|
67591
|
+
}
|
|
67592
|
+
}
|
|
67593
|
+
});
|
|
67594
|
+
|
|
67595
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/artifact-resolver.js
|
|
67596
|
+
var require_artifact_resolver = __commonJS({
|
|
67597
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/artifact-resolver.js"(exports2) {
|
|
67598
|
+
"use strict";
|
|
67599
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
67600
|
+
exports2.classifyByName = classifyByName;
|
|
67601
|
+
exports2.resolve = resolve;
|
|
67602
|
+
var resolver_yaml_js_1 = require_resolver_yaml();
|
|
67603
|
+
var resolver_glob_js_1 = require_resolver_glob();
|
|
67604
|
+
var DEFAULT_GENERATED = ["**/generated/**", "**/gen/**"];
|
|
67605
|
+
var VENDOR_GLOBS = ["**/node_modules/**", "**/vendor/**"];
|
|
67606
|
+
function normalizePath(p) {
|
|
67607
|
+
let s = p.replace(/\\/g, "/").trim();
|
|
67608
|
+
while (s.startsWith("./"))
|
|
67609
|
+
s = s.slice(2);
|
|
67610
|
+
return s;
|
|
67611
|
+
}
|
|
67612
|
+
function dirname(p) {
|
|
67613
|
+
const i = p.lastIndexOf("/");
|
|
67614
|
+
return i === -1 ? "" : p.slice(0, i);
|
|
67615
|
+
}
|
|
67616
|
+
function basename(p) {
|
|
67617
|
+
const i = p.lastIndexOf("/");
|
|
67618
|
+
return i === -1 ? p : p.slice(i + 1);
|
|
67619
|
+
}
|
|
67620
|
+
function extname(p) {
|
|
67621
|
+
const b = basename(p);
|
|
67622
|
+
const i = b.lastIndexOf(".");
|
|
67623
|
+
return i === -1 ? "" : b.slice(i + 1).toLowerCase();
|
|
67624
|
+
}
|
|
67625
|
+
function resolveRelative(dir, rel) {
|
|
67626
|
+
const parts = (dir ? dir.split("/") : []).concat(normalizePath(rel).split("/"));
|
|
67627
|
+
const out = [];
|
|
67628
|
+
for (const seg of parts) {
|
|
67629
|
+
if (seg === "" || seg === ".")
|
|
67630
|
+
continue;
|
|
67631
|
+
if (seg === "..")
|
|
67632
|
+
out.pop();
|
|
67633
|
+
else
|
|
67634
|
+
out.push(seg);
|
|
67635
|
+
}
|
|
67636
|
+
return out.join("/");
|
|
67637
|
+
}
|
|
67638
|
+
function classifyByName(path) {
|
|
67639
|
+
const b = basename(path).toLowerCase();
|
|
67640
|
+
const ext = extname(path);
|
|
67641
|
+
const yamlJson = ext === "yaml" || ext === "yml" || ext === "json";
|
|
67642
|
+
if (yamlJson && (b.includes("openapi") || b.includes("swagger")))
|
|
67643
|
+
return "openapi";
|
|
67644
|
+
if (yamlJson && b.includes("asyncapi"))
|
|
67645
|
+
return "asyncapi";
|
|
67646
|
+
if (ext === "graphql" || ext === "gql")
|
|
67647
|
+
return "graphql";
|
|
67648
|
+
if (ext === "proto")
|
|
67649
|
+
return "grpc";
|
|
67650
|
+
if (b === "mcp.json" || b === "tools-catalog.json")
|
|
67651
|
+
return "mcp_manifest";
|
|
67652
|
+
return null;
|
|
67653
|
+
}
|
|
67654
|
+
function classifyByContent(text) {
|
|
67655
|
+
if (!text)
|
|
67656
|
+
return null;
|
|
67657
|
+
if (/(^|\n)\s*["']?openapi["']?\s*:\s*["']?[23]/.test(text) || /swagger\s*:/.test(text) && /paths\s*:/.test(text))
|
|
67658
|
+
return "openapi";
|
|
67659
|
+
if (/(^|\n)\s*["']?asyncapi["']?\s*:/.test(text))
|
|
67660
|
+
return "asyncapi";
|
|
67661
|
+
if (/\btype\s+Query\b|\btype\s+Mutation\b|\bschema\s*\{/.test(text))
|
|
67662
|
+
return "graphql";
|
|
67663
|
+
if (/syntax\s*=\s*["']proto[23]["']/.test(text))
|
|
67664
|
+
return "grpc";
|
|
67665
|
+
try {
|
|
67666
|
+
const j = JSON.parse(text);
|
|
67667
|
+
if (j && Array.isArray(j.tools) && j.tools.some((t) => t && typeof t === "object" && "inputSchema" in t))
|
|
67668
|
+
return "mcp_manifest";
|
|
67669
|
+
} catch {
|
|
67670
|
+
}
|
|
67671
|
+
return null;
|
|
67672
|
+
}
|
|
67673
|
+
function isMcpByNameNeedingContent(path) {
|
|
67674
|
+
const b = basename(path).toLowerCase();
|
|
67675
|
+
return extname(path) === "json" && b.includes("mcp") && b !== "mcp.json";
|
|
67676
|
+
}
|
|
67677
|
+
var REF_RE = /\$ref["']?\s*:\s*["']?([^"'\s,}]+)["']?/g;
|
|
67678
|
+
function scanRefs(text) {
|
|
67679
|
+
const out = [];
|
|
67680
|
+
let m;
|
|
67681
|
+
REF_RE.lastIndex = 0;
|
|
67682
|
+
while ((m = REF_RE.exec(text)) !== null)
|
|
67683
|
+
out.push(m[1]);
|
|
67684
|
+
return out;
|
|
67685
|
+
}
|
|
67686
|
+
function isExternalRef(ref) {
|
|
67687
|
+
return /^[a-z][a-z0-9+.-]*:\/\//i.test(ref) || ref.startsWith("//");
|
|
67688
|
+
}
|
|
67689
|
+
function isInternalRef(ref) {
|
|
67690
|
+
return ref.startsWith("#");
|
|
67691
|
+
}
|
|
67692
|
+
function splitRef(ref) {
|
|
67693
|
+
const i = ref.indexOf("#");
|
|
67694
|
+
return i === -1 ? { file: ref, pointer: "" } : { file: ref.slice(0, i), pointer: ref.slice(i + 1) };
|
|
67695
|
+
}
|
|
67696
|
+
function jsonPointer(doc, pointer) {
|
|
67697
|
+
if (pointer === "" || pointer === "/")
|
|
67698
|
+
return doc;
|
|
67699
|
+
const parts = pointer.replace(/^\//, "").split("/").map((p) => p.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
67700
|
+
let cur = doc;
|
|
67701
|
+
for (const part of parts) {
|
|
67702
|
+
if (cur && typeof cur === "object" && part in cur)
|
|
67703
|
+
cur = cur[part];
|
|
67704
|
+
else
|
|
67705
|
+
return void 0;
|
|
67706
|
+
}
|
|
67707
|
+
return cur;
|
|
67708
|
+
}
|
|
67709
|
+
function slugify(s) {
|
|
67710
|
+
return s.replace(/[^A-Za-z0-9]+/g, "_");
|
|
67711
|
+
}
|
|
67712
|
+
var RefError = class extends Error {
|
|
67713
|
+
reason;
|
|
67714
|
+
related;
|
|
67715
|
+
constructor(reason, related) {
|
|
67716
|
+
super(reason);
|
|
67717
|
+
this.reason = reason;
|
|
67718
|
+
this.related = related;
|
|
67719
|
+
}
|
|
67720
|
+
};
|
|
67721
|
+
function assembleSide(rootPath, rootText, refSide, input, config, deps) {
|
|
67722
|
+
const maxDepth = config.maxRefDepth ?? 8;
|
|
67723
|
+
let root;
|
|
67724
|
+
try {
|
|
67725
|
+
root = (0, resolver_yaml_js_1.parseDoc)(rootText);
|
|
67726
|
+
} catch (e) {
|
|
67727
|
+
if (e instanceof resolver_yaml_js_1.YamlLiteError)
|
|
67728
|
+
throw new RefError("parse_error");
|
|
67729
|
+
throw e;
|
|
67730
|
+
}
|
|
67731
|
+
const components = {};
|
|
67732
|
+
const inline = (node, curDir, depth, stack) => {
|
|
67733
|
+
if (Array.isArray(node))
|
|
67734
|
+
return node.map((n) => inline(n, curDir, depth, stack));
|
|
67735
|
+
if (node && typeof node === "object") {
|
|
67736
|
+
const rec = node;
|
|
67737
|
+
if (typeof rec.$ref === "string") {
|
|
67738
|
+
const ref = rec.$ref;
|
|
67739
|
+
if (isExternalRef(ref))
|
|
67740
|
+
throw new RefError("external_ref_forbidden");
|
|
67741
|
+
if (isInternalRef(ref))
|
|
67742
|
+
return { ...rec };
|
|
67743
|
+
const { file, pointer } = splitRef(ref);
|
|
67744
|
+
const targetPath = resolveRelative(curDir, file);
|
|
67745
|
+
const key = `${targetPath}#${pointer}`;
|
|
67746
|
+
if (depth + 1 > maxDepth)
|
|
67747
|
+
throw new RefError("ref_depth_exceeded", targetPath);
|
|
67748
|
+
if (stack.has(key))
|
|
67749
|
+
throw new RefError("ref_cycle", targetPath);
|
|
67750
|
+
const blob = getBlob(input, refSide, targetPath);
|
|
67751
|
+
if (blob === null || blob === void 0)
|
|
67752
|
+
throw new RefError("missing_ref_target", targetPath);
|
|
67753
|
+
if (typeof blob === "object")
|
|
67754
|
+
throw new RefError(blob.error, targetPath);
|
|
67755
|
+
deps.add(targetPath);
|
|
67756
|
+
let targetDoc;
|
|
67757
|
+
try {
|
|
67758
|
+
targetDoc = (0, resolver_yaml_js_1.parseDoc)(blob);
|
|
67759
|
+
} catch {
|
|
67760
|
+
throw new RefError("parse_error", targetPath);
|
|
67761
|
+
}
|
|
67762
|
+
const resolved = jsonPointer(targetDoc, pointer);
|
|
67763
|
+
if (resolved === void 0)
|
|
67764
|
+
throw new RefError("missing_ref_target", targetPath);
|
|
67765
|
+
const inlined = inline(resolved, dirname(targetPath), depth + 1, /* @__PURE__ */ new Set([...stack, key]));
|
|
67766
|
+
const slug = slugify(`${targetPath}__${pointer}`);
|
|
67767
|
+
components[slug] = inlined;
|
|
67768
|
+
return { $ref: `#/components/${slug}` };
|
|
67769
|
+
}
|
|
67770
|
+
const out = {};
|
|
67771
|
+
for (const k of Object.keys(rec))
|
|
67772
|
+
out[k] = inline(rec[k], curDir, depth, stack);
|
|
67773
|
+
return out;
|
|
67774
|
+
}
|
|
67775
|
+
return node;
|
|
67776
|
+
};
|
|
67777
|
+
const inlinedRoot = inline(root, dirname(rootPath), 0, /* @__PURE__ */ new Set());
|
|
67778
|
+
if (Object.keys(components).length > 0) {
|
|
67779
|
+
const existing = inlinedRoot.components && typeof inlinedRoot.components === "object" ? inlinedRoot.components : {};
|
|
67780
|
+
inlinedRoot.components = { ...existing, ...components };
|
|
67781
|
+
}
|
|
67782
|
+
return (0, resolver_yaml_js_1.stableStringify)(inlinedRoot);
|
|
67783
|
+
}
|
|
67784
|
+
function getBlob(input, ref, path) {
|
|
67785
|
+
return input.blobs[`${ref}:${path}`];
|
|
67786
|
+
}
|
|
67787
|
+
function loadRoot(path, type, input, config) {
|
|
67788
|
+
const baseBlob = getBlob(input, input.baseRef, path);
|
|
67789
|
+
const headBlob = getBlob(input, input.headRef, path);
|
|
67790
|
+
if (baseBlob && typeof baseBlob === "object")
|
|
67791
|
+
return { unresolved: { path, reason: baseBlob.error } };
|
|
67792
|
+
if (headBlob && typeof headBlob === "object")
|
|
67793
|
+
return { unresolved: { path, reason: headBlob.error } };
|
|
67794
|
+
const baseNull = baseBlob === null || baseBlob === void 0;
|
|
67795
|
+
const headNull = headBlob === null || headBlob === void 0;
|
|
67796
|
+
if (baseNull && headNull)
|
|
67797
|
+
return { unresolved: { path, reason: "empty_changed_contract" } };
|
|
67798
|
+
let before = baseNull ? "" : baseBlob;
|
|
67799
|
+
let after = headNull ? "" : headBlob;
|
|
67800
|
+
const deps = /* @__PURE__ */ new Set();
|
|
67801
|
+
const assemble = (type === "openapi" || type === "asyncapi") && (config.openApiAssembly ?? "bundle_inline") === "bundle_inline";
|
|
67802
|
+
if (assemble) {
|
|
67803
|
+
try {
|
|
67804
|
+
if (before !== "" && scanRefs(before).some((r) => !isInternalRef(r)))
|
|
67805
|
+
before = assembleSide(path, before, input.baseRef, input, config, deps);
|
|
67806
|
+
if (after !== "" && scanRefs(after).some((r) => !isInternalRef(r)))
|
|
67807
|
+
after = assembleSide(path, after, input.headRef, input, config, deps);
|
|
67808
|
+
} catch (e) {
|
|
67809
|
+
if (e instanceof RefError)
|
|
67810
|
+
return { unresolved: { path, reason: e.reason, ...e.related ? { related_paths: [e.related] } : {} } };
|
|
67811
|
+
throw e;
|
|
67812
|
+
}
|
|
67813
|
+
}
|
|
67814
|
+
const id = input.repository ? `${input.repository}:${type}:${path}` : `${type}:${path}`;
|
|
67815
|
+
return { artifact: { id, type, before, after }, deps: [...deps] };
|
|
67816
|
+
}
|
|
67817
|
+
function selectGroups(candidates, config, generatedGlobs) {
|
|
67818
|
+
const n = candidates.length;
|
|
67819
|
+
const parent = Array.from({ length: n }, (_, i) => i);
|
|
67820
|
+
const find = (x) => {
|
|
67821
|
+
while (parent[x] !== x) {
|
|
67822
|
+
parent[x] = parent[parent[x]];
|
|
67823
|
+
x = parent[x];
|
|
67824
|
+
}
|
|
67825
|
+
return x;
|
|
67826
|
+
};
|
|
67827
|
+
const union = (a, b) => {
|
|
67828
|
+
const ra = find(a);
|
|
67829
|
+
const rb = find(b);
|
|
67830
|
+
if (ra !== rb)
|
|
67831
|
+
parent[Math.max(ra, rb)] = Math.min(ra, rb);
|
|
67832
|
+
};
|
|
67833
|
+
if (Array.isArray(config.forceSameSurfaceGroup)) {
|
|
67834
|
+
const idxs = candidates.map((c, i) => config.forceSameSurfaceGroup.includes(c.path) ? i : -1).filter((i) => i >= 0);
|
|
67835
|
+
for (let k = 1; k < idxs.length; k += 1)
|
|
67836
|
+
union(idxs[0], idxs[k]);
|
|
67837
|
+
}
|
|
67838
|
+
const byType = /* @__PURE__ */ new Map();
|
|
67839
|
+
candidates.forEach((c, i) => {
|
|
67840
|
+
const a = byType.get(c.type) ?? [];
|
|
67841
|
+
a.push(i);
|
|
67842
|
+
byType.set(c.type, a);
|
|
67843
|
+
});
|
|
67844
|
+
for (const idxs of byType.values()) {
|
|
67845
|
+
const gen = idxs.filter((i) => (0, resolver_glob_js_1.matchAny)(generatedGlobs, candidates[i].path));
|
|
67846
|
+
if (gen.length > 0 && gen.length < idxs.length)
|
|
67847
|
+
for (let k = 1; k < idxs.length; k += 1)
|
|
67848
|
+
union(idxs[0], idxs[k]);
|
|
67849
|
+
}
|
|
67850
|
+
const groups = /* @__PURE__ */ new Map();
|
|
67851
|
+
for (let i = 0; i < n; i += 1) {
|
|
67852
|
+
const r = find(i);
|
|
67853
|
+
const g = groups.get(r) ?? [];
|
|
67854
|
+
g.push(i);
|
|
67855
|
+
groups.set(r, g);
|
|
67856
|
+
}
|
|
67857
|
+
const selections = [];
|
|
67858
|
+
const chosen = [];
|
|
67859
|
+
const ambiguous = [];
|
|
67860
|
+
for (const g of groups.values()) {
|
|
67861
|
+
const members = g.map((i) => candidates[i].path).sort();
|
|
67862
|
+
if (members.length === 1) {
|
|
67863
|
+
chosen.push(candidates[g[0]]);
|
|
67864
|
+
selections.push({ chosen: members[0], deferred: [], reason: "single" });
|
|
67865
|
+
continue;
|
|
67866
|
+
}
|
|
67867
|
+
const prefRanked = members.map((p) => ({ p, rank: (0, resolver_glob_js_1.firstMatchIndex)(config.ssotPrefer, p) })).filter((x) => x.rank >= 0);
|
|
67868
|
+
if (prefRanked.length > 0) {
|
|
67869
|
+
prefRanked.sort((a, b) => a.rank - b.rank || (a.p < b.p ? -1 : 1));
|
|
67870
|
+
const chosenPath = prefRanked[0].p;
|
|
67871
|
+
chosen.push(candidates[g.find((i) => candidates[i].path === chosenPath)]);
|
|
67872
|
+
selections.push({ chosen: chosenPath, deferred: members.filter((m) => m !== chosenPath), reason: "ssotPrefer" });
|
|
67873
|
+
continue;
|
|
67874
|
+
}
|
|
67875
|
+
const nongen = members.filter((p) => !(0, resolver_glob_js_1.matchAny)(generatedGlobs, p));
|
|
67876
|
+
if (nongen.length === 1) {
|
|
67877
|
+
const chosenPath = nongen[0];
|
|
67878
|
+
chosen.push(candidates[g.find((i) => candidates[i].path === chosenPath)]);
|
|
67879
|
+
selections.push({ chosen: chosenPath, deferred: members.filter((m) => m !== chosenPath), reason: "generated_deprioritized" });
|
|
67880
|
+
continue;
|
|
67881
|
+
}
|
|
67882
|
+
ambiguous.push(...members);
|
|
67883
|
+
}
|
|
67884
|
+
return { selections, chosen, ambiguous };
|
|
67885
|
+
}
|
|
67886
|
+
function resolve(input, config = {}) {
|
|
67887
|
+
const generatedGlobs = config.generatedGlobs ?? DEFAULT_GENERATED;
|
|
67888
|
+
const seen = /* @__PURE__ */ new Set();
|
|
67889
|
+
const paths = [];
|
|
67890
|
+
for (const raw of Array.isArray(input.changedFiles) ? input.changedFiles : []) {
|
|
67891
|
+
const p = normalizePath(raw);
|
|
67892
|
+
if (p && !seen.has(p)) {
|
|
67893
|
+
seen.add(p);
|
|
67894
|
+
paths.push(p);
|
|
67895
|
+
}
|
|
67896
|
+
}
|
|
67897
|
+
const candidates = [];
|
|
67898
|
+
const ignored = [];
|
|
67899
|
+
for (const p of paths) {
|
|
67900
|
+
if ((0, resolver_glob_js_1.matchAny)(VENDOR_GLOBS, p)) {
|
|
67901
|
+
ignored.push(p);
|
|
67902
|
+
continue;
|
|
67903
|
+
}
|
|
67904
|
+
let type = config.pathTypeHints?.[p] ?? classifyByName(p);
|
|
67905
|
+
if (type === null || isMcpByNameNeedingContent(p)) {
|
|
67906
|
+
const peek = firstDefinedText(getBlob(input, input.headRef, p), getBlob(input, input.baseRef, p));
|
|
67907
|
+
const sniff = classifyByContent(peek);
|
|
67908
|
+
if (isMcpByNameNeedingContent(p))
|
|
67909
|
+
type = sniff === "mcp_manifest" ? "mcp_manifest" : type ?? sniff;
|
|
67910
|
+
else
|
|
67911
|
+
type = sniff;
|
|
67912
|
+
}
|
|
67913
|
+
if (type)
|
|
67914
|
+
candidates.push({ path: p, type });
|
|
67915
|
+
else
|
|
67916
|
+
ignored.push(p);
|
|
67917
|
+
}
|
|
67918
|
+
const unresolved = [];
|
|
67919
|
+
let effectiveCandidates = candidates;
|
|
67920
|
+
if (config.requireSsotIfConfigured && Array.isArray(config.ssotPrefer)) {
|
|
67921
|
+
const missing = config.ssotPrefer.filter((pref) => !hasGlobChar(pref) && !existsInTree(input, pref));
|
|
67922
|
+
const hasGenerated = candidates.some((c) => (0, resolver_glob_js_1.matchAny)(generatedGlobs, c.path));
|
|
67923
|
+
if (missing.length > 0 && hasGenerated) {
|
|
67924
|
+
for (const pref of missing)
|
|
67925
|
+
unresolved.push({ path: pref, reason: "config_ssot_missing" });
|
|
67926
|
+
effectiveCandidates = candidates.filter((c) => !(0, resolver_glob_js_1.matchAny)(generatedGlobs, c.path));
|
|
67927
|
+
}
|
|
67928
|
+
}
|
|
67929
|
+
const { selections, chosen, ambiguous } = selectGroups(effectiveCandidates, config, generatedGlobs);
|
|
67930
|
+
for (const p of [...new Set(ambiguous)].sort())
|
|
67931
|
+
unresolved.push({ path: p, reason: "ambiguous_ssot" });
|
|
67932
|
+
const artifacts = [];
|
|
67933
|
+
const selBySel = new Map(selections.map((s) => [s.chosen, s]));
|
|
67934
|
+
for (const c of chosen.slice().sort((a, b) => a.path < b.path ? -1 : 1)) {
|
|
67935
|
+
const res = loadRoot(c.path, c.type, input, config);
|
|
67936
|
+
if ("artifact" in res) {
|
|
67937
|
+
artifacts.push(res.artifact);
|
|
67938
|
+
const sel = selBySel.get(c.path);
|
|
67939
|
+
for (const dep of res.deps) {
|
|
67940
|
+
const idx = ignored.indexOf(dep);
|
|
67941
|
+
if (idx >= 0)
|
|
67942
|
+
ignored.splice(idx, 1);
|
|
67943
|
+
if (sel && !sel.deferred.includes(dep) && dep !== c.path)
|
|
67944
|
+
sel.deferred.push(dep);
|
|
67945
|
+
}
|
|
67946
|
+
if (sel)
|
|
67947
|
+
sel.deferred.sort();
|
|
67948
|
+
} else {
|
|
67949
|
+
unresolved.push(res.unresolved);
|
|
67950
|
+
}
|
|
67951
|
+
}
|
|
67952
|
+
const A = artifacts.length;
|
|
67953
|
+
const U = unresolved.length;
|
|
67954
|
+
const chosenCount = chosen.length;
|
|
67955
|
+
let coverage;
|
|
67956
|
+
if (chosenCount === 0 && U === 0)
|
|
67957
|
+
coverage = "EMPTY";
|
|
67958
|
+
else if (U === 0 && A >= 1 && A === chosenCount)
|
|
67959
|
+
coverage = "COMPLETE";
|
|
67960
|
+
else if (A >= 1 && U >= 1)
|
|
67961
|
+
coverage = "PARTIAL";
|
|
67962
|
+
else
|
|
67963
|
+
coverage = "UNRESOLVED";
|
|
67964
|
+
artifacts.sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
|
|
67965
|
+
unresolved.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : a.reason < b.reason ? -1 : a.reason > b.reason ? 1 : 0);
|
|
67966
|
+
ignored.sort();
|
|
67967
|
+
const contractDiscovered = effectiveCandidates.map((c) => c.path).slice().sort();
|
|
67968
|
+
return {
|
|
67969
|
+
artifacts,
|
|
67970
|
+
unresolved,
|
|
67971
|
+
coverage,
|
|
67972
|
+
report: {
|
|
67973
|
+
version: "artifact-resolver-report/1.0",
|
|
67974
|
+
baseRef: input.baseRef,
|
|
67975
|
+
headRef: input.headRef,
|
|
67976
|
+
contract_paths_discovered: contractDiscovered,
|
|
67977
|
+
ignored_non_contract: ignored,
|
|
67978
|
+
ssot_selections: selections,
|
|
67979
|
+
claim: {
|
|
67980
|
+
artifacts_ready_for_preflight: coverage === "COMPLETE" || coverage === "EMPTY",
|
|
67981
|
+
produces_verdict: false
|
|
67982
|
+
}
|
|
67983
|
+
}
|
|
67984
|
+
};
|
|
67985
|
+
}
|
|
67986
|
+
function firstDefinedText(...vals) {
|
|
67987
|
+
for (const v of vals)
|
|
67988
|
+
if (typeof v === "string")
|
|
67989
|
+
return v;
|
|
67990
|
+
return void 0;
|
|
67991
|
+
}
|
|
67992
|
+
function hasGlobChar(p) {
|
|
67993
|
+
return /[*?]/.test(p);
|
|
67994
|
+
}
|
|
67995
|
+
function existsInTree(input, path) {
|
|
67996
|
+
return typeof getBlob(input, input.baseRef, path) === "string" || typeof getBlob(input, input.headRef, path) === "string";
|
|
67997
|
+
}
|
|
67998
|
+
}
|
|
67999
|
+
});
|
|
68000
|
+
|
|
68001
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/tool-registry.js
|
|
68002
|
+
var require_tool_registry = __commonJS({
|
|
68003
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/tool-registry.js"(exports2) {
|
|
68004
|
+
"use strict";
|
|
68005
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
68006
|
+
exports2.RegistryConstructionError = void 0;
|
|
68007
|
+
exports2.guardToolRegistry = guardToolRegistry;
|
|
68008
|
+
var guard_js_1 = require_guard();
|
|
68009
|
+
var artifact_resolver_js_1 = require_artifact_resolver();
|
|
68010
|
+
var RegistryConstructionError = class extends Error {
|
|
68011
|
+
code;
|
|
68012
|
+
toolName;
|
|
68013
|
+
constructor(code, message, toolName) {
|
|
68014
|
+
super(message);
|
|
68015
|
+
this.name = "RegistryConstructionError";
|
|
68016
|
+
this.code = code;
|
|
68017
|
+
this.toolName = toolName;
|
|
68018
|
+
}
|
|
68019
|
+
};
|
|
68020
|
+
exports2.RegistryConstructionError = RegistryConstructionError;
|
|
68021
|
+
var MUTATING_GENERIC = ["write", "edit", "create", "update", "delete", "remove", "apply_patch", "applypatch", "str_replace", "notebook_edit", "multi_edit", "insert"];
|
|
68022
|
+
var MUTATING_SHELL = ["bash", "shell", "terminal", "run_command", "exec", "powershell"];
|
|
68023
|
+
var MUTATING_VCS = ["git_commit", "git_push", "git_merge", "commit", "push"];
|
|
68024
|
+
var MUTATING_DEPLOY = ["deploy", "kubectl_apply", "helm_upgrade", "release"];
|
|
68025
|
+
var MUTATING_PUBLISH = ["npm_publish", "publish_package", "twine_upload", "cargo_publish"];
|
|
68026
|
+
var MUTATING_SCHEMA = ["register_tools", "update_manifest", "mcp_register"];
|
|
68027
|
+
var READONLY = ["read", "grep", "glob", "search", "list", "ls", "cat", "get", "fetch", "web_search", "browser_navigate"];
|
|
68028
|
+
function isMutatingClass(cls) {
|
|
68029
|
+
return cls !== "readonly";
|
|
68030
|
+
}
|
|
68031
|
+
function matchesAny(hay, patterns) {
|
|
68032
|
+
return patterns.some((p) => hay.includes(p));
|
|
68033
|
+
}
|
|
68034
|
+
function heuristicClass(name) {
|
|
68035
|
+
const n = String(name || "").toLowerCase();
|
|
68036
|
+
if (matchesAny(n, MUTATING_SHELL))
|
|
68037
|
+
return "mutating_shell";
|
|
68038
|
+
if (matchesAny(n, MUTATING_VCS) || n.startsWith("git_"))
|
|
68039
|
+
return "mutating_vcs";
|
|
68040
|
+
if (matchesAny(n, MUTATING_DEPLOY))
|
|
68041
|
+
return "mutating_deploy";
|
|
68042
|
+
if (matchesAny(n, MUTATING_PUBLISH))
|
|
68043
|
+
return "mutating_publish";
|
|
68044
|
+
if (matchesAny(n, MUTATING_SCHEMA))
|
|
68045
|
+
return "mutating_schema";
|
|
68046
|
+
if (matchesAny(n, MUTATING_GENERIC))
|
|
68047
|
+
return "mutating";
|
|
68048
|
+
if (matchesAny(n, READONLY))
|
|
68049
|
+
return "readonly";
|
|
68050
|
+
return null;
|
|
68051
|
+
}
|
|
68052
|
+
function resolveClass(tool, config, unknownPolicy) {
|
|
68053
|
+
const classify = config.classify || {};
|
|
68054
|
+
if (Object.prototype.hasOwnProperty.call(classify, tool.name))
|
|
68055
|
+
return { cls: classify[tool.name], source: "classify" };
|
|
68056
|
+
if (tool.mutationClass)
|
|
68057
|
+
return { cls: tool.mutationClass, source: "mutationClass" };
|
|
68058
|
+
if (Array.isArray(config.forceReadonly) && config.forceReadonly.includes(tool.name))
|
|
68059
|
+
return { cls: "readonly", source: "forceReadonly" };
|
|
68060
|
+
const h = heuristicClass(tool.name);
|
|
68061
|
+
if (h)
|
|
68062
|
+
return { cls: h, source: "heuristic" };
|
|
68063
|
+
if (unknownPolicy === "reject") {
|
|
68064
|
+
throw new RegistryConstructionError("UNKNOWN_TOOL", `tool '${tool.name}' is unclassified and unknownToolPolicy='reject'`, tool.name);
|
|
68065
|
+
}
|
|
68066
|
+
return { cls: unknownPolicy === "readonly" ? "readonly" : "mutating", source: "unknown" };
|
|
68067
|
+
}
|
|
68068
|
+
function operationForClass(cls, name, guardOperation) {
|
|
68069
|
+
switch (cls) {
|
|
68070
|
+
case "mutating_shell":
|
|
68071
|
+
return "tool_call";
|
|
68072
|
+
case "mutating_vcs":
|
|
68073
|
+
return /merge/i.test(name) ? "merge" : "tool_call";
|
|
68074
|
+
case "mutating_deploy":
|
|
68075
|
+
return "deploy";
|
|
68076
|
+
case "mutating_publish":
|
|
68077
|
+
return "publish";
|
|
68078
|
+
case "mutating_schema":
|
|
68079
|
+
return "tool_call";
|
|
68080
|
+
case "mutating":
|
|
68081
|
+
default:
|
|
68082
|
+
return guardOperation ?? "tool_call";
|
|
68083
|
+
}
|
|
68084
|
+
}
|
|
68085
|
+
function defaultBinder(tool, args) {
|
|
68086
|
+
const d = { toolName: tool.name, arguments: args };
|
|
68087
|
+
if (!args || typeof args !== "object")
|
|
68088
|
+
return d;
|
|
68089
|
+
const a = args;
|
|
68090
|
+
if (Array.isArray(a.artifacts)) {
|
|
68091
|
+
d.artifacts = a.artifacts;
|
|
68092
|
+
return d;
|
|
68093
|
+
}
|
|
68094
|
+
const path = typeof a.path === "string" ? a.path : "";
|
|
68095
|
+
if (!path)
|
|
68096
|
+
return d;
|
|
68097
|
+
const type = (0, artifact_resolver_js_1.classifyByName)(path);
|
|
68098
|
+
if (!type)
|
|
68099
|
+
return d;
|
|
68100
|
+
const bothSides = (oldS, newS) => typeof oldS === "string" && oldS.length > 0 && typeof newS === "string" && newS.length > 0;
|
|
68101
|
+
if (Array.isArray(a.edits)) {
|
|
68102
|
+
const lifted = [];
|
|
68103
|
+
for (let i = 0; i < a.edits.length; i++) {
|
|
68104
|
+
const e = a.edits[i];
|
|
68105
|
+
if (!e || typeof e !== "object")
|
|
68106
|
+
continue;
|
|
68107
|
+
const er = e;
|
|
68108
|
+
if (!bothSides(er.old_string, er.new_string))
|
|
68109
|
+
continue;
|
|
68110
|
+
lifted.push({
|
|
68111
|
+
id: `${type}:${path}#${i}`,
|
|
68112
|
+
type,
|
|
68113
|
+
before: er.old_string,
|
|
68114
|
+
after: er.new_string
|
|
68115
|
+
});
|
|
68116
|
+
}
|
|
68117
|
+
if (lifted.length > 0)
|
|
68118
|
+
d.artifacts = lifted;
|
|
68119
|
+
return d;
|
|
68120
|
+
}
|
|
68121
|
+
if (bothSides(a.old_string, a.new_string)) {
|
|
68122
|
+
d.artifacts = [{
|
|
68123
|
+
id: `${type}:${path}`,
|
|
68124
|
+
type,
|
|
68125
|
+
before: a.old_string,
|
|
68126
|
+
after: a.new_string
|
|
68127
|
+
}];
|
|
68128
|
+
}
|
|
68129
|
+
return d;
|
|
68130
|
+
}
|
|
68131
|
+
var RAW_EXECUTORS = /* @__PURE__ */ new WeakMap();
|
|
68132
|
+
function freezeTool(t) {
|
|
68133
|
+
Object.freeze(t._coderifts);
|
|
68134
|
+
return Object.freeze(t);
|
|
68135
|
+
}
|
|
68136
|
+
function passthroughProtected(tool, cls) {
|
|
68137
|
+
const rawExecute = tool.execute;
|
|
68138
|
+
const protectedTool = {
|
|
68139
|
+
name: tool.name,
|
|
68140
|
+
description: tool.description,
|
|
68141
|
+
inputSchema: tool.inputSchema,
|
|
68142
|
+
meta: tool.meta,
|
|
68143
|
+
execute: async (args) => rawExecute(args),
|
|
68144
|
+
// new function, not === rawExecute
|
|
68145
|
+
_coderifts: { guarded: false, mutationClass: cls }
|
|
68146
|
+
};
|
|
68147
|
+
RAW_EXECUTORS.set(protectedTool, rawExecute);
|
|
68148
|
+
return freezeTool(protectedTool);
|
|
68149
|
+
}
|
|
68150
|
+
function wrapWithGuard(tool, cls, config) {
|
|
68151
|
+
const rawExecute = tool.execute;
|
|
68152
|
+
const guardBase = config.guard;
|
|
68153
|
+
const operation = operationForClass(cls, tool.name, guardBase.operation);
|
|
68154
|
+
const guardCfg = { ...guardBase, operation };
|
|
68155
|
+
const binder = config.binders && config.binders[tool.name] || ((t, a) => defaultBinder(t, a));
|
|
68156
|
+
const protectedTool = {
|
|
68157
|
+
name: tool.name,
|
|
68158
|
+
description: tool.description,
|
|
68159
|
+
inputSchema: tool.inputSchema,
|
|
68160
|
+
meta: tool.meta,
|
|
68161
|
+
execute: async (args) => {
|
|
68162
|
+
const call = binder(tool, args, cls);
|
|
68163
|
+
return (0, guard_js_1.guardToolCall)(call, async (_envelope, redacted) => rawExecute(redacted ? redacted.arguments : args), guardCfg);
|
|
68164
|
+
},
|
|
68165
|
+
_coderifts: { guarded: true, mutationClass: cls, operation }
|
|
68166
|
+
};
|
|
68167
|
+
RAW_EXECUTORS.set(protectedTool, rawExecute);
|
|
68168
|
+
return freezeTool(protectedTool);
|
|
68169
|
+
}
|
|
68170
|
+
function guardToolRegistry(rawTools, config = {}) {
|
|
68171
|
+
const failHard = config.failOnUnguardedMutator !== false;
|
|
68172
|
+
const unknownPolicy = config.unknownToolPolicy ?? "mutating";
|
|
68173
|
+
const input = Array.isArray(rawTools) ? rawTools : [];
|
|
68174
|
+
for (const tool of input) {
|
|
68175
|
+
if (!tool || typeof tool.name !== "string" || tool.name.trim() === "") {
|
|
68176
|
+
throw new RegistryConstructionError("INVALID_TOOL", "a tool has a missing or empty name");
|
|
68177
|
+
}
|
|
68178
|
+
if (typeof tool.execute !== "function") {
|
|
68179
|
+
throw new RegistryConstructionError("INVALID_TOOL", `tool '${tool.name}' has no execute function`, tool.name);
|
|
68180
|
+
}
|
|
68181
|
+
}
|
|
68182
|
+
const seen = /* @__PURE__ */ new Set();
|
|
68183
|
+
for (const tool of input) {
|
|
68184
|
+
if (seen.has(tool.name)) {
|
|
68185
|
+
throw new RegistryConstructionError("DUPLICATE_TOOL_NAME", `duplicate tool name '${tool.name}'`, tool.name);
|
|
68186
|
+
}
|
|
68187
|
+
seen.add(tool.name);
|
|
68188
|
+
}
|
|
68189
|
+
const sorted = input.slice().sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
68190
|
+
const guardedMutators = [];
|
|
68191
|
+
const readonlyPassthrough = [];
|
|
68192
|
+
const warnings = [];
|
|
68193
|
+
const staged = [];
|
|
68194
|
+
let anyForced = false;
|
|
68195
|
+
let anyUnknownReadonly = false;
|
|
68196
|
+
for (const tool of sorted) {
|
|
68197
|
+
const { cls, source } = resolveClass(tool, config, unknownPolicy);
|
|
68198
|
+
const forced = cls === "readonly" && (source === "classify" || source === "forceReadonly") && isMutating(heuristicClass(tool.name));
|
|
68199
|
+
if (forced) {
|
|
68200
|
+
anyForced = true;
|
|
68201
|
+
warnings.push(`force_readonly_on_mutator_heuristic:${tool.name}`);
|
|
68202
|
+
}
|
|
68203
|
+
if (source === "unknown" && cls === "readonly")
|
|
68204
|
+
anyUnknownReadonly = true;
|
|
68205
|
+
staged.push({ tool, cls, forced });
|
|
68206
|
+
}
|
|
68207
|
+
if (anyForced && failHard) {
|
|
68208
|
+
throw new RegistryConstructionError("FORCE_READONLY_MUTATOR", `forceReadonly/classify downgraded a heuristic mutator to readonly while failOnUnguardedMutator is true`);
|
|
68209
|
+
}
|
|
68210
|
+
const willWrap = staged.some((s) => isMutating(s.cls) && !s.forced);
|
|
68211
|
+
const validGuard = !!(config.guard && config.guard.client);
|
|
68212
|
+
if (willWrap && !validGuard) {
|
|
68213
|
+
throw new RegistryConstructionError("GUARD_CONFIG_INVALID", "a mutating tool is present but config.guard.client is missing/invalid");
|
|
68214
|
+
}
|
|
68215
|
+
const protectedTools = [];
|
|
68216
|
+
for (const { tool, cls, forced } of staged) {
|
|
68217
|
+
if (cls === "readonly") {
|
|
68218
|
+
readonlyPassthrough.push(tool.name);
|
|
68219
|
+
protectedTools.push(passthroughProtected(tool, "readonly"));
|
|
68220
|
+
} else {
|
|
68221
|
+
guardedMutators.push(tool.name);
|
|
68222
|
+
protectedTools.push(wrapWithGuard(tool, cls, config));
|
|
68223
|
+
}
|
|
68224
|
+
void forced;
|
|
68225
|
+
}
|
|
68226
|
+
for (const p of protectedTools) {
|
|
68227
|
+
if (isMutatingClass(p._coderifts.mutationClass) && p._coderifts.guarded !== true) {
|
|
68228
|
+
throw new RegistryConstructionError("GUARD_CONFIG_INVALID", `invariant violated: '${p.name}' is a mutator exposed without a guard`, p.name);
|
|
68229
|
+
}
|
|
68230
|
+
}
|
|
68231
|
+
const M = guardedMutators.length;
|
|
68232
|
+
const G = guardedMutators.length;
|
|
68233
|
+
let coverage;
|
|
68234
|
+
if (anyForced) {
|
|
68235
|
+
coverage = "BYPASSED";
|
|
68236
|
+
} else if (unknownPolicy === "readonly" && anyUnknownReadonly) {
|
|
68237
|
+
coverage = "PARTIAL";
|
|
68238
|
+
} else if (M === G) {
|
|
68239
|
+
coverage = "COMPLETE";
|
|
68240
|
+
} else {
|
|
68241
|
+
coverage = "PARTIAL";
|
|
68242
|
+
}
|
|
68243
|
+
if (unknownPolicy === "readonly" && anyUnknownReadonly && !warnings.includes("unknown_treated_as_readonly")) {
|
|
68244
|
+
warnings.push("unknown_treated_as_readonly");
|
|
68245
|
+
}
|
|
68246
|
+
const inescapableRuntime = coverage === "COMPLETE" && failHard;
|
|
68247
|
+
const report = {
|
|
68248
|
+
version: "guard-tool-registry-report/1.0",
|
|
68249
|
+
coverage,
|
|
68250
|
+
protected_tools: protectedTools.map((p) => p.name),
|
|
68251
|
+
guarded_mutators: guardedMutators.slice(),
|
|
68252
|
+
readonly_passthrough: readonlyPassthrough.slice(),
|
|
68253
|
+
unguarded_mutators: [],
|
|
68254
|
+
// strict impl: always [] (COMPLETE ⇒ [] by G4; forced tools are readonly)
|
|
68255
|
+
unknown_treated_as: unknownPolicy,
|
|
68256
|
+
claim: {
|
|
68257
|
+
inescapable_runtime: inescapableRuntime,
|
|
68258
|
+
inescapable_merge: false,
|
|
68259
|
+
inescapable_deploy: false
|
|
68260
|
+
},
|
|
68261
|
+
siblings: {
|
|
68262
|
+
merge_gate: "required_separate_#7",
|
|
68263
|
+
artifact_resolver: "sibling_#4"
|
|
68264
|
+
},
|
|
68265
|
+
warnings
|
|
68266
|
+
};
|
|
68267
|
+
Object.freeze(report.claim);
|
|
68268
|
+
Object.freeze(report.siblings);
|
|
68269
|
+
Object.freeze(report);
|
|
68270
|
+
return {
|
|
68271
|
+
tools: Object.freeze(protectedTools),
|
|
68272
|
+
coverage,
|
|
68273
|
+
report
|
|
68274
|
+
};
|
|
68275
|
+
}
|
|
68276
|
+
function isMutating(cls) {
|
|
68277
|
+
return cls != null && cls !== "readonly";
|
|
68278
|
+
}
|
|
68279
|
+
}
|
|
68280
|
+
});
|
|
68281
|
+
|
|
68282
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/merge-gate.js
|
|
68283
|
+
var require_merge_gate = __commonJS({
|
|
68284
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/merge-gate.js"(exports2) {
|
|
68285
|
+
"use strict";
|
|
68286
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
68287
|
+
exports2.gateDecision = gateDecision;
|
|
68288
|
+
function normSha(s) {
|
|
68289
|
+
return String(s == null ? "" : s).trim().toLowerCase();
|
|
68290
|
+
}
|
|
68291
|
+
function normOp(o) {
|
|
68292
|
+
return String(o == null ? "" : o).trim().toLowerCase();
|
|
68293
|
+
}
|
|
68294
|
+
function sameHead(a, b, allowPrefix) {
|
|
68295
|
+
const na = normSha(a);
|
|
68296
|
+
const nb = normSha(b);
|
|
68297
|
+
if (!na || !nb)
|
|
68298
|
+
return false;
|
|
68299
|
+
if (na === nb)
|
|
68300
|
+
return true;
|
|
68301
|
+
if (allowPrefix && na.length >= 7 && nb.length >= 7 && (na.startsWith(nb) || nb.startsWith(na)))
|
|
68302
|
+
return true;
|
|
68303
|
+
return false;
|
|
68304
|
+
}
|
|
68305
|
+
function isAllowClass(receipt, allowWarnMerge) {
|
|
68306
|
+
const dec = receipt.decision;
|
|
68307
|
+
const decisionOk = dec === "ALLOW" || dec === "WARN" && allowWarnMerge === true;
|
|
68308
|
+
if (!decisionOk)
|
|
68309
|
+
return false;
|
|
68310
|
+
const ea = receipt.execution_action;
|
|
68311
|
+
if (ea === void 0 || ea === null || ea === "")
|
|
68312
|
+
return true;
|
|
68313
|
+
return ea === "CONTINUE" || ea === "CONTINUE_WITH_MONITORING";
|
|
68314
|
+
}
|
|
68315
|
+
function targetMatches(targetId, repository) {
|
|
68316
|
+
const t = String(targetId).toLowerCase();
|
|
68317
|
+
const r = String(repository).toLowerCase();
|
|
68318
|
+
return t === r || t === `repo:${r}` || t.endsWith(`:${r}`) || t.endsWith(`/${r}`);
|
|
68319
|
+
}
|
|
68320
|
+
function gateDecision(input) {
|
|
68321
|
+
const rc = input.requiredContext || {};
|
|
68322
|
+
const protection = rc.protection || { enforcement: "UNKNOWN", admin_bypass_possible: true };
|
|
68323
|
+
const enforcement_state = protection.enforcement;
|
|
68324
|
+
const allowPending = input.allowPending ?? rc.allowPending ?? false;
|
|
68325
|
+
const allowWarnMerge = input.allowWarnMerge ?? rc.allowWarnMerge ?? false;
|
|
68326
|
+
const allowPrefix = input.allowPrefixCompare ?? rc.allowPrefixCompare ?? false;
|
|
68327
|
+
const receipt = input.receipt;
|
|
68328
|
+
const detail = {
|
|
68329
|
+
prHeadSha: normSha(input.prHeadSha),
|
|
68330
|
+
bound_head_sha: receipt ? normSha(receipt.bound_head_sha) : null,
|
|
68331
|
+
decision: receipt ? String(receipt.decision) : null
|
|
68332
|
+
};
|
|
68333
|
+
const fail = (state, reason) => ({
|
|
68334
|
+
merge_allowed: false,
|
|
68335
|
+
state,
|
|
68336
|
+
reason,
|
|
68337
|
+
enforcement_state,
|
|
68338
|
+
inescapable_merge: false,
|
|
68339
|
+
detail
|
|
68340
|
+
});
|
|
68341
|
+
if (!input.prHeadSha || String(input.prHeadSha).trim() === "") {
|
|
68342
|
+
return fail(allowPending ? "pending" : "failure", "inputs_incomplete");
|
|
68343
|
+
}
|
|
68344
|
+
if (receipt === null || receipt === void 0) {
|
|
68345
|
+
return fail(allowPending ? "pending" : "failure", "no_receipt");
|
|
68346
|
+
}
|
|
68347
|
+
if (receipt.currently_authorized !== true) {
|
|
68348
|
+
return fail("failure", "receipt_not_authorized");
|
|
68349
|
+
}
|
|
68350
|
+
const op = rc.operation ?? "merge";
|
|
68351
|
+
if (receipt.operation == null || normOp(receipt.operation) !== normOp(op)) {
|
|
68352
|
+
return fail("failure", "operation_mismatch");
|
|
68353
|
+
}
|
|
68354
|
+
if (!sameHead(receipt.bound_head_sha, input.prHeadSha, allowPrefix)) {
|
|
68355
|
+
return fail("failure", "stale_head");
|
|
68356
|
+
}
|
|
68357
|
+
if (rc.expected_fingerprint != null && receipt.verdict_fingerprint !== rc.expected_fingerprint) {
|
|
68358
|
+
return fail("failure", "fingerprint_mismatch");
|
|
68359
|
+
}
|
|
68360
|
+
if (rc.expected_body_hash != null && receipt.body_hash !== rc.expected_body_hash) {
|
|
68361
|
+
return fail("failure", "body_hash_mismatch");
|
|
68362
|
+
}
|
|
68363
|
+
if (rc.repository && receipt.target_id && !targetMatches(receipt.target_id, rc.repository)) {
|
|
68364
|
+
return fail("failure", "target_mismatch");
|
|
68365
|
+
}
|
|
68366
|
+
if (!isAllowClass(receipt, allowWarnMerge)) {
|
|
68367
|
+
return fail("failure", "decision_not_allow");
|
|
68368
|
+
}
|
|
68369
|
+
const inescapable_merge = enforcement_state === "ENFORCING" && protection.admin_bypass_possible === false;
|
|
68370
|
+
let residual;
|
|
68371
|
+
if (!inescapable_merge) {
|
|
68372
|
+
if (enforcement_state === "ENFORCING")
|
|
68373
|
+
residual = "admin_bypass_open";
|
|
68374
|
+
else if (enforcement_state === "ADVISORY")
|
|
68375
|
+
residual = "protection_advisory_only";
|
|
68376
|
+
else
|
|
68377
|
+
residual = "protection_not_configured";
|
|
68378
|
+
} else {
|
|
68379
|
+
if (protection.required_check_app_bound === true) {
|
|
68380
|
+
} else if (protection.required_check_app_bound === false) {
|
|
68381
|
+
residual = "required_check_app_not_bound";
|
|
68382
|
+
} else {
|
|
68383
|
+
residual = "required_check_app_binding_unknown";
|
|
68384
|
+
}
|
|
68385
|
+
}
|
|
68386
|
+
return {
|
|
68387
|
+
merge_allowed: true,
|
|
68388
|
+
state: "success",
|
|
68389
|
+
reason: "allow_current_head",
|
|
68390
|
+
enforcement_state,
|
|
68391
|
+
inescapable_merge,
|
|
68392
|
+
...residual ? { residual } : {},
|
|
68393
|
+
detail
|
|
68394
|
+
};
|
|
68395
|
+
}
|
|
68396
|
+
}
|
|
68397
|
+
});
|
|
68398
|
+
|
|
68399
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/deploy-gate.js
|
|
68400
|
+
var require_deploy_gate = __commonJS({
|
|
68401
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/deploy-gate.js"(exports2) {
|
|
68402
|
+
"use strict";
|
|
68403
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
68404
|
+
exports2.deployGate = deployGate;
|
|
68405
|
+
function norm(s) {
|
|
68406
|
+
return String(s == null ? "" : s).trim().toLowerCase();
|
|
68407
|
+
}
|
|
68408
|
+
function sameNorm(a, b, allowPrefix) {
|
|
68409
|
+
const na = norm(a);
|
|
68410
|
+
const nb = norm(b);
|
|
68411
|
+
if (!na || !nb)
|
|
68412
|
+
return false;
|
|
68413
|
+
if (na === nb)
|
|
68414
|
+
return true;
|
|
68415
|
+
if (allowPrefix && na.length >= 7 && nb.length >= 7 && (na.startsWith(nb) || nb.startsWith(na)))
|
|
68416
|
+
return true;
|
|
68417
|
+
return false;
|
|
68418
|
+
}
|
|
68419
|
+
function isAllowClass(receipt, allowWarnDeploy) {
|
|
68420
|
+
const dec = receipt.decision;
|
|
68421
|
+
const decisionOk = dec === "ALLOW" || dec === "WARN" && allowWarnDeploy === true;
|
|
68422
|
+
if (!decisionOk)
|
|
68423
|
+
return false;
|
|
68424
|
+
const ea = receipt.execution_action;
|
|
68425
|
+
if (ea === void 0 || ea === null || ea === "")
|
|
68426
|
+
return true;
|
|
68427
|
+
return ea === "CONTINUE" || ea === "CONTINUE_WITH_MONITORING";
|
|
68428
|
+
}
|
|
68429
|
+
function idMatchesName(targetId, name) {
|
|
68430
|
+
const t = norm(targetId);
|
|
68431
|
+
const r = norm(name);
|
|
68432
|
+
return t === r || t === `svc:${r}` || t === `repo:${r}` || t.endsWith(`:${r}`) || t.endsWith(`/${r}`);
|
|
68433
|
+
}
|
|
68434
|
+
function deployGate(input) {
|
|
68435
|
+
const target = input.deployTarget || {};
|
|
68436
|
+
const rc = input.requiredContext || {};
|
|
68437
|
+
const enf = rc.enforcement || { enforcement: "UNKNOWN", bypass_possible: true };
|
|
68438
|
+
const enforcement_state = enf.enforcement;
|
|
68439
|
+
const opRequired = rc.operation ?? "deploy";
|
|
68440
|
+
const requireEnv = enforcement_state === "ENFORCING" || rc.require_bound_environment !== false;
|
|
68441
|
+
const requireArt = enforcement_state === "ENFORCING" || rc.require_bound_artifact !== false;
|
|
68442
|
+
const allowPending = input.allowPending ?? rc.allowPending ?? false;
|
|
68443
|
+
const allowWarnDeploy = input.allowWarnDeploy ?? rc.allowWarnDeploy ?? false;
|
|
68444
|
+
const allowPrefix = input.allowPrefixCompare ?? rc.allowPrefixCompare ?? false;
|
|
68445
|
+
const receipt = input.receipt;
|
|
68446
|
+
const detail = {
|
|
68447
|
+
environment: norm(target.environment),
|
|
68448
|
+
artifact_id: norm(target.artifact_id),
|
|
68449
|
+
bound_environment: receipt && receipt.bound_environment != null ? norm(receipt.bound_environment) : null,
|
|
68450
|
+
bound_artifact_id: receipt && receipt.bound_artifact_id != null ? norm(receipt.bound_artifact_id) : null,
|
|
68451
|
+
operation: receipt && receipt.operation != null ? String(receipt.operation) : null
|
|
68452
|
+
};
|
|
68453
|
+
const deny = (state, reason) => ({
|
|
68454
|
+
deploy_allowed: false,
|
|
68455
|
+
state,
|
|
68456
|
+
reason,
|
|
68457
|
+
enforcement_state,
|
|
68458
|
+
inescapable_deploy: false,
|
|
68459
|
+
detail
|
|
68460
|
+
});
|
|
68461
|
+
if (!target.environment || String(target.environment).trim() === "" || !target.artifact_id || String(target.artifact_id).trim() === "") {
|
|
68462
|
+
return deny(allowPending ? "pending" : "failure", "inputs_incomplete");
|
|
68463
|
+
}
|
|
68464
|
+
if (receipt === null || receipt === void 0) {
|
|
68465
|
+
return deny(allowPending ? "pending" : "failure", "no_receipt");
|
|
68466
|
+
}
|
|
68467
|
+
if (receipt.currently_authorized !== true) {
|
|
68468
|
+
return deny("failure", "receipt_not_authorized");
|
|
68469
|
+
}
|
|
68470
|
+
if (receipt.operation == null || norm(receipt.operation) !== norm(opRequired)) {
|
|
68471
|
+
return deny("failure", "operation_mismatch");
|
|
68472
|
+
}
|
|
68473
|
+
if (requireEnv) {
|
|
68474
|
+
if (!receipt.bound_environment || !sameNorm(receipt.bound_environment, target.environment, allowPrefix)) {
|
|
68475
|
+
return deny("failure", "env_mismatch");
|
|
68476
|
+
}
|
|
68477
|
+
} else if (receipt.bound_environment && !sameNorm(receipt.bound_environment, target.environment, allowPrefix)) {
|
|
68478
|
+
return deny("failure", "env_mismatch");
|
|
68479
|
+
}
|
|
68480
|
+
if (requireArt) {
|
|
68481
|
+
if (!receipt.bound_artifact_id || !sameNorm(receipt.bound_artifact_id, target.artifact_id, allowPrefix)) {
|
|
68482
|
+
return deny("failure", "stale_artifact");
|
|
68483
|
+
}
|
|
68484
|
+
} else if (receipt.bound_artifact_id && !sameNorm(receipt.bound_artifact_id, target.artifact_id, allowPrefix)) {
|
|
68485
|
+
return deny("failure", "stale_artifact");
|
|
68486
|
+
}
|
|
68487
|
+
if (rc.expected_fingerprint != null && receipt.verdict_fingerprint !== rc.expected_fingerprint) {
|
|
68488
|
+
return deny("failure", "fingerprint_mismatch");
|
|
68489
|
+
}
|
|
68490
|
+
if (rc.expected_body_hash != null && receipt.body_hash !== rc.expected_body_hash) {
|
|
68491
|
+
return deny("failure", "body_hash_mismatch");
|
|
68492
|
+
}
|
|
68493
|
+
if (rc.service && receipt.target_id) {
|
|
68494
|
+
if (!idMatchesName(receipt.target_id, rc.service))
|
|
68495
|
+
return deny("failure", "target_mismatch");
|
|
68496
|
+
} else if (rc.repository && receipt.target_id) {
|
|
68497
|
+
if (!idMatchesName(receipt.target_id, rc.repository))
|
|
68498
|
+
return deny("failure", "target_mismatch");
|
|
68499
|
+
}
|
|
68500
|
+
if (!isAllowClass(receipt, allowWarnDeploy)) {
|
|
68501
|
+
return deny("failure", "decision_not_allow");
|
|
68502
|
+
}
|
|
68503
|
+
const inescapable_deploy = enforcement_state === "ENFORCING" && enf.bypass_possible === false;
|
|
68504
|
+
let residual;
|
|
68505
|
+
if (!inescapable_deploy) {
|
|
68506
|
+
if (enforcement_state === "ENFORCING")
|
|
68507
|
+
residual = "bypass_open";
|
|
68508
|
+
else
|
|
68509
|
+
residual = "enforcement_not_configured";
|
|
68510
|
+
}
|
|
68511
|
+
return {
|
|
68512
|
+
deploy_allowed: true,
|
|
68513
|
+
state: "success",
|
|
68514
|
+
reason: "allow_current_deploy",
|
|
68515
|
+
enforcement_state,
|
|
68516
|
+
inescapable_deploy,
|
|
68517
|
+
...residual ? { residual } : {},
|
|
68518
|
+
detail
|
|
68519
|
+
};
|
|
68520
|
+
}
|
|
68521
|
+
}
|
|
68522
|
+
});
|
|
68523
|
+
|
|
68524
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/coverage-report.js
|
|
68525
|
+
var require_coverage_report = __commonJS({
|
|
68526
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/coverage-report.js"(exports2) {
|
|
68527
|
+
"use strict";
|
|
68528
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
68529
|
+
exports2.coverageReport = coverageReport;
|
|
68530
|
+
var TEMPLATES = {
|
|
68531
|
+
claim_fully_enforced: "All applicable CodeRifts placements are enforcing and non-bypassable for this target. Residuals outside tetrad (e.g. infra break-glass) may still exist.",
|
|
68532
|
+
claim_partially_enforced: "Partial enforcement: some applicable placements enforce; open gaps: {residuals}.",
|
|
68533
|
+
claim_advisory_only: "CodeRifts is present but no applicable placement is fully enforcing. Gaps: {residuals}.",
|
|
68534
|
+
claim_content_blocked: "Contract artifact content is not fully resolved; enforcement of preflight content is incomplete. Gaps: {residuals}.",
|
|
68535
|
+
claim_unknown: "One or more applicable placements cannot be observed. Cannot attest full enforcement. Gaps: {residuals}.",
|
|
68536
|
+
claim_not_applicable: "No CodeRifts placements are in scope for this target."
|
|
68537
|
+
};
|
|
68538
|
+
var OVERALL_TO_KEY = {
|
|
68539
|
+
FULLY_ENFORCED: "claim_fully_enforced",
|
|
68540
|
+
PARTIALLY_ENFORCED: "claim_partially_enforced",
|
|
68541
|
+
ADVISORY_ONLY: "claim_advisory_only",
|
|
68542
|
+
CONTENT_BLOCKED: "claim_content_blocked",
|
|
68543
|
+
UNKNOWN: "claim_unknown",
|
|
68544
|
+
NOT_APPLICABLE: "claim_not_applicable"
|
|
68545
|
+
};
|
|
68546
|
+
function computeRuntime(applicable, input) {
|
|
68547
|
+
if (!applicable)
|
|
68548
|
+
return { strength: "EXCLUDED", residuals: [], summary: { enforcement_or_coverage: input?.coverage ?? "N/A", inescapable_flag: input?.inescapable_runtime ?? null } };
|
|
68549
|
+
if (input == null)
|
|
68550
|
+
return { strength: "UNKNOWN", residuals: ["runtime_state_missing"], summary: { enforcement_or_coverage: "MISSING", inescapable_flag: null } };
|
|
68551
|
+
const residuals = [...input.residuals ?? []];
|
|
68552
|
+
let strength;
|
|
68553
|
+
if (input.coverage === "COMPLETE" && input.inescapable_runtime === true)
|
|
68554
|
+
strength = "ENFORCING";
|
|
68555
|
+
else if (input.coverage === "UNKNOWN")
|
|
68556
|
+
strength = "UNKNOWN";
|
|
68557
|
+
else
|
|
68558
|
+
strength = "WEAK";
|
|
68559
|
+
if (input.coverage === "BYPASSED")
|
|
68560
|
+
residuals.push("runtime_bypassed");
|
|
68561
|
+
return { strength, residuals, summary: { enforcement_or_coverage: input.coverage, inescapable_flag: input.inescapable_runtime } };
|
|
68562
|
+
}
|
|
68563
|
+
function computeMerge(applicable, input) {
|
|
68564
|
+
if (!applicable)
|
|
68565
|
+
return { strength: "EXCLUDED", residuals: [], summary: { enforcement_or_coverage: input?.enforcement_state ?? "N/A", inescapable_flag: input?.inescapable_merge ?? null } };
|
|
68566
|
+
if (input == null)
|
|
68567
|
+
return { strength: "UNKNOWN", residuals: ["merge_state_missing"], summary: { enforcement_or_coverage: "MISSING", inescapable_flag: null } };
|
|
68568
|
+
const residuals = [...input.residuals ?? []];
|
|
68569
|
+
let strength;
|
|
68570
|
+
if (input.inescapable_merge === true && input.enforcement_state === "ENFORCING")
|
|
68571
|
+
strength = "ENFORCING";
|
|
68572
|
+
else if (input.inescapable_merge === true) {
|
|
68573
|
+
strength = "WEAK";
|
|
68574
|
+
residuals.push("inescapable_flag_inconsistent");
|
|
68575
|
+
} else if (input.enforcement_state === "UNKNOWN")
|
|
68576
|
+
strength = "UNKNOWN";
|
|
68577
|
+
else
|
|
68578
|
+
strength = "WEAK";
|
|
68579
|
+
if (strength === "WEAK") {
|
|
68580
|
+
if (input.enforcement_state === "ENFORCING" && input.inescapable_merge === false)
|
|
68581
|
+
residuals.push("admin_bypass_open");
|
|
68582
|
+
else if (input.enforcement_state === "ABSENT")
|
|
68583
|
+
residuals.push("merge_gate_not_configured");
|
|
68584
|
+
else if (input.enforcement_state === "ADVISORY")
|
|
68585
|
+
residuals.push("merge_gate_advisory");
|
|
68586
|
+
}
|
|
68587
|
+
return { strength, residuals, summary: { enforcement_or_coverage: input.enforcement_state, inescapable_flag: input.inescapable_merge } };
|
|
68588
|
+
}
|
|
68589
|
+
function computeDeploy(applicable, input) {
|
|
68590
|
+
if (!applicable)
|
|
68591
|
+
return { strength: "EXCLUDED", residuals: [], summary: { enforcement_or_coverage: input?.enforcement_state ?? "N/A", inescapable_flag: input?.inescapable_deploy ?? null } };
|
|
68592
|
+
if (input == null)
|
|
68593
|
+
return { strength: "UNKNOWN", residuals: ["deploy_state_missing"], summary: { enforcement_or_coverage: "MISSING", inescapable_flag: null } };
|
|
68594
|
+
const residuals = [...input.residuals ?? []];
|
|
68595
|
+
let strength;
|
|
68596
|
+
if (input.inescapable_deploy === true && input.enforcement_state === "ENFORCING")
|
|
68597
|
+
strength = "ENFORCING";
|
|
68598
|
+
else if (input.inescapable_deploy === true) {
|
|
68599
|
+
strength = "WEAK";
|
|
68600
|
+
residuals.push("inescapable_flag_inconsistent");
|
|
68601
|
+
} else if (input.enforcement_state === "UNKNOWN")
|
|
68602
|
+
strength = "UNKNOWN";
|
|
68603
|
+
else
|
|
68604
|
+
strength = "WEAK";
|
|
68605
|
+
if (strength === "WEAK") {
|
|
68606
|
+
if (input.enforcement_state === "ENFORCING" && input.inescapable_deploy === false)
|
|
68607
|
+
residuals.push("bypass_open");
|
|
68608
|
+
else if (input.enforcement_state === "ABSENT")
|
|
68609
|
+
residuals.push("deploy_path_ungated");
|
|
68610
|
+
else if (input.enforcement_state === "ADVISORY")
|
|
68611
|
+
residuals.push("deploy_gate_advisory");
|
|
68612
|
+
}
|
|
68613
|
+
return { strength, residuals, summary: { enforcement_or_coverage: input.enforcement_state, inescapable_flag: input.inescapable_deploy } };
|
|
68614
|
+
}
|
|
68615
|
+
function computeContent(applicable, input) {
|
|
68616
|
+
if (!applicable)
|
|
68617
|
+
return { strength: "EXCLUDED", residuals: [], summary: { enforcement_or_coverage: input?.coverage ?? "N/A", inescapable_flag: input?.artifacts_ready ?? null } };
|
|
68618
|
+
if (input == null)
|
|
68619
|
+
return { strength: "UNKNOWN", residuals: ["content_state_missing"], summary: { enforcement_or_coverage: "MISSING", inescapable_flag: null } };
|
|
68620
|
+
const residuals = [...input.residuals ?? []];
|
|
68621
|
+
let strength;
|
|
68622
|
+
if (input.coverage === "COMPLETE" || input.coverage === "EMPTY")
|
|
68623
|
+
strength = "ENFORCING";
|
|
68624
|
+
else if (input.coverage === "UNRESOLVED") {
|
|
68625
|
+
strength = "WEAK";
|
|
68626
|
+
residuals.push("content_unresolved");
|
|
68627
|
+
} else if (input.coverage === "PARTIAL") {
|
|
68628
|
+
strength = "WEAK";
|
|
68629
|
+
residuals.push("content_partial");
|
|
68630
|
+
} else
|
|
68631
|
+
strength = "UNKNOWN";
|
|
68632
|
+
return { strength, residuals, summary: { enforcement_or_coverage: input.coverage, inescapable_flag: input.artifacts_ready ?? null } };
|
|
68633
|
+
}
|
|
68634
|
+
function coverageReport(input) {
|
|
68635
|
+
const applicability = input.applicability || { runtime: false, merge: false, deploy: false, content: false };
|
|
68636
|
+
const computed = {
|
|
68637
|
+
runtime: computeRuntime(applicability.runtime === true, input.runtime),
|
|
68638
|
+
merge: computeMerge(applicability.merge === true, input.merge),
|
|
68639
|
+
deploy: computeDeploy(applicability.deploy === true, input.deploy),
|
|
68640
|
+
content: computeContent(applicability.content === true, input.content)
|
|
68641
|
+
};
|
|
68642
|
+
const order = ["runtime", "merge", "deploy", "content"];
|
|
68643
|
+
const isApplicable = (p) => applicability[p] === true;
|
|
68644
|
+
const applicableStrengths = order.filter(isApplicable).map((p) => computed[p].strength);
|
|
68645
|
+
const contentApplicable = isApplicable("content");
|
|
68646
|
+
const contentUnresolved = contentApplicable && input.content != null && input.content.coverage === "UNRESOLVED";
|
|
68647
|
+
const weakPlacements = order.filter((p) => isApplicable(p) && computed[p].strength === "WEAK");
|
|
68648
|
+
let overall;
|
|
68649
|
+
if (applicableStrengths.length === 0) {
|
|
68650
|
+
overall = "NOT_APPLICABLE";
|
|
68651
|
+
} else if (applicableStrengths.every((s) => s === "ENFORCING")) {
|
|
68652
|
+
overall = "FULLY_ENFORCED";
|
|
68653
|
+
} else if (applicableStrengths.some((s) => s === "WEAK") && applicableStrengths.some((s) => s === "ENFORCING")) {
|
|
68654
|
+
overall = contentUnresolved ? "CONTENT_BLOCKED" : "PARTIALLY_ENFORCED";
|
|
68655
|
+
} else if (applicableStrengths.some((s) => s === "WEAK")) {
|
|
68656
|
+
overall = contentUnresolved && weakPlacements.every((p) => p === "content") ? "CONTENT_BLOCKED" : "ADVISORY_ONLY";
|
|
68657
|
+
} else {
|
|
68658
|
+
overall = "UNKNOWN";
|
|
68659
|
+
}
|
|
68660
|
+
const residualSet = /* @__PURE__ */ new Set();
|
|
68661
|
+
for (const p of order)
|
|
68662
|
+
if (isApplicable(p))
|
|
68663
|
+
for (const r of computed[p].residuals)
|
|
68664
|
+
residualSet.add(r);
|
|
68665
|
+
const residuals = [...residualSet].sort();
|
|
68666
|
+
const honest_claim_key = OVERALL_TO_KEY[overall];
|
|
68667
|
+
const honest_claim_language = TEMPLATES[honest_claim_key].replace("{residuals}", residuals.length ? residuals.join(", ") : "none");
|
|
68668
|
+
const flags = {
|
|
68669
|
+
may_claim_inescapable_runtime: isApplicable("runtime") && computed.runtime.strength === "ENFORCING",
|
|
68670
|
+
may_claim_inescapable_merge: isApplicable("merge") && computed.merge.strength === "ENFORCING",
|
|
68671
|
+
may_claim_inescapable_deploy: isApplicable("deploy") && computed.deploy.strength === "ENFORCING",
|
|
68672
|
+
may_claim_full_tetrad: overall === "FULLY_ENFORCED"
|
|
68673
|
+
};
|
|
68674
|
+
const per_placement = order.map((p) => ({
|
|
68675
|
+
placement: p,
|
|
68676
|
+
applicable: isApplicable(p),
|
|
68677
|
+
strength: computed[p].strength,
|
|
68678
|
+
summary: computed[p].summary,
|
|
68679
|
+
residuals: isApplicable(p) ? [...new Set(computed[p].residuals)].sort() : []
|
|
68680
|
+
}));
|
|
68681
|
+
return { overall_coverage: overall, per_placement, residuals, honest_claim_key, honest_claim_language, flags };
|
|
68682
|
+
}
|
|
68683
|
+
}
|
|
68684
|
+
});
|
|
68685
|
+
|
|
68686
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/with-coderifts.js
|
|
68687
|
+
var require_with_coderifts = __commonJS({
|
|
68688
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/with-coderifts.js"(exports2) {
|
|
68689
|
+
"use strict";
|
|
68690
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
68691
|
+
exports2.withCodeRifts = withCodeRifts;
|
|
68692
|
+
var tool_registry_js_1 = require_tool_registry();
|
|
68693
|
+
var COMPOSITION_CALL_POLICY_COMPLETE = false;
|
|
68694
|
+
var RESIDUAL_CALL_POLICY_INCOMPLETE = "composition_call_policy_incomplete";
|
|
68695
|
+
var RESIDUAL_FORCED_READONLY = "composition_forced_readonly_on_heuristic_mutator";
|
|
68696
|
+
var RESIDUAL_UNKNOWN_READONLY = "composition_unknown_treated_as_readonly";
|
|
68697
|
+
var COVERAGE_STRENGTH = {
|
|
68698
|
+
COMPLETE: 3,
|
|
68699
|
+
PARTIAL: 2,
|
|
68700
|
+
BYPASSED: 1,
|
|
68701
|
+
UNKNOWN: 0
|
|
68702
|
+
};
|
|
68703
|
+
function coverageRank(coverage) {
|
|
68704
|
+
return Object.prototype.hasOwnProperty.call(COVERAGE_STRENGTH, coverage) ? COVERAGE_STRENGTH[coverage] : void 0;
|
|
68705
|
+
}
|
|
68706
|
+
async function safeOnOutcome(onOutcome, payload) {
|
|
68707
|
+
try {
|
|
68708
|
+
await Promise.resolve(onOutcome(payload));
|
|
68709
|
+
} catch {
|
|
68710
|
+
}
|
|
68711
|
+
}
|
|
68712
|
+
function wrapGuardedForObservation(tool, onOutcome) {
|
|
68713
|
+
const innerExecute = tool.execute;
|
|
68714
|
+
const toolName = tool.name;
|
|
68715
|
+
const shell = {
|
|
68716
|
+
name: tool.name,
|
|
68717
|
+
description: tool.description,
|
|
68718
|
+
inputSchema: tool.inputSchema,
|
|
68719
|
+
meta: tool.meta,
|
|
68720
|
+
_coderifts: tool._coderifts,
|
|
68721
|
+
execute: async (args) => {
|
|
68722
|
+
const outcome = await innerExecute(args);
|
|
68723
|
+
await safeOnOutcome(onOutcome, {
|
|
68724
|
+
toolName,
|
|
68725
|
+
// Guarded execute always returns a GuardOutcome from guardToolCall; assert the type for callers.
|
|
68726
|
+
outcome
|
|
68727
|
+
});
|
|
68728
|
+
return outcome;
|
|
68729
|
+
}
|
|
68730
|
+
};
|
|
68731
|
+
if (!Object.isFrozen(shell._coderifts))
|
|
68732
|
+
Object.freeze(shell._coderifts);
|
|
68733
|
+
return Object.freeze(shell);
|
|
68734
|
+
}
|
|
68735
|
+
function withCodeRifts(input) {
|
|
68736
|
+
if (!input || typeof input !== "object") {
|
|
68737
|
+
throw new Error("withCodeRifts: input object is required");
|
|
68738
|
+
}
|
|
68739
|
+
const problems = [];
|
|
68740
|
+
if (typeof input.operation !== "string" || input.operation.trim() === "") {
|
|
68741
|
+
problems.push("`operation` is required and must be a non-empty string (receipts bind to an operation; merge != deploy, so there is no safe default)");
|
|
68742
|
+
}
|
|
68743
|
+
if (input.client == null) {
|
|
68744
|
+
problems.push("`client` is required at construction (guardToolRegistry needs config.guard.client to wrap any mutating tool)");
|
|
68745
|
+
}
|
|
68746
|
+
if (input.requireCoverage !== void 0 && coverageRank(input.requireCoverage) === void 0) {
|
|
68747
|
+
problems.push(`\`requireCoverage\` must be one of COMPLETE | PARTIAL | BYPASSED | UNKNOWN (got ${JSON.stringify(input.requireCoverage)})`);
|
|
68748
|
+
}
|
|
68749
|
+
if (problems.length > 0) {
|
|
68750
|
+
throw new Error(`withCodeRifts: construction aborted \u2014 ${problems.length} condition(s):
|
|
68751
|
+
` + problems.map((p) => ` - ${p}`).join("\n"));
|
|
68752
|
+
}
|
|
68753
|
+
const reg = input.registry ?? {};
|
|
68754
|
+
const guard = { client: input.client, operation: input.operation };
|
|
68755
|
+
if (input.onEvent !== void 0) {
|
|
68756
|
+
guard.onEvent = input.onEvent;
|
|
68757
|
+
}
|
|
68758
|
+
if (input.previousReceipt !== void 0) {
|
|
68759
|
+
guard.previousReceipt = input.previousReceipt;
|
|
68760
|
+
}
|
|
68761
|
+
const config = {
|
|
68762
|
+
guard,
|
|
68763
|
+
unknownToolPolicy: reg.unknownToolPolicy ?? "mutating",
|
|
68764
|
+
classify: reg.classify,
|
|
68765
|
+
binders: reg.binders,
|
|
68766
|
+
forceReadonly: reg.forceReadonly,
|
|
68767
|
+
failOnUnguardedMutator: reg.failOnUnguardedMutator
|
|
68768
|
+
};
|
|
68769
|
+
const { tools, report } = (0, tool_registry_js_1.guardToolRegistry)(input.tools, config);
|
|
68770
|
+
if (input.requireCoverage !== void 0) {
|
|
68771
|
+
const requiredRank = coverageRank(input.requireCoverage);
|
|
68772
|
+
const actualRank = coverageRank(report.coverage) ?? -1;
|
|
68773
|
+
if (requiredRank !== void 0 && actualRank < requiredRank) {
|
|
68774
|
+
throw new Error(`withCodeRifts: requireCoverage not met \u2014 registry coverage '${report.coverage}' is weaker than required '${input.requireCoverage}' (strength ordering COMPLETE > PARTIAL > BYPASSED > UNKNOWN). requireCoverage constrains the REGISTRY tool-boundary surface ONLY; a green construction here is NOT a product-level runtime-inescapability guarantee \u2014 composition_assurance.inescapable_runtime stays false until receipt carry-forward and a freshness-safe prior for write-style calls land.`);
|
|
68775
|
+
}
|
|
68776
|
+
}
|
|
68777
|
+
const compositionInescapableRuntime = report.claim.inescapable_runtime && COMPOSITION_CALL_POLICY_COMPLETE;
|
|
68778
|
+
const residuals = [RESIDUAL_CALL_POLICY_INCOMPLETE];
|
|
68779
|
+
if (report.warnings.some((w) => w.startsWith("force_readonly_on_mutator_heuristic:"))) {
|
|
68780
|
+
residuals.push(RESIDUAL_FORCED_READONLY);
|
|
68781
|
+
}
|
|
68782
|
+
if (report.warnings.includes("unknown_treated_as_readonly")) {
|
|
68783
|
+
residuals.push(RESIDUAL_UNKNOWN_READONLY);
|
|
68784
|
+
}
|
|
68785
|
+
const composition_assurance = {
|
|
68786
|
+
coverage: "PARTIAL",
|
|
68787
|
+
inescapable_runtime: compositionInescapableRuntime,
|
|
68788
|
+
residuals
|
|
68789
|
+
};
|
|
68790
|
+
let toolsOut = tools;
|
|
68791
|
+
if (input.onOutcome) {
|
|
68792
|
+
const onOutcome = input.onOutcome;
|
|
68793
|
+
toolsOut = Object.freeze(tools.map((t) => t._coderifts.guarded ? wrapGuardedForObservation(t, onOutcome) : t));
|
|
68794
|
+
}
|
|
68795
|
+
const result = {
|
|
68796
|
+
tools: toolsOut,
|
|
68797
|
+
registry_report: report,
|
|
68798
|
+
composition_assurance
|
|
68799
|
+
};
|
|
68800
|
+
if (input.repository !== void 0)
|
|
68801
|
+
result.repository = input.repository;
|
|
68802
|
+
return result;
|
|
68803
|
+
}
|
|
68804
|
+
}
|
|
68805
|
+
});
|
|
68806
|
+
|
|
68807
|
+
// node_modules/@coderifts/agent-guard/dist/cjs/index.js
|
|
68808
|
+
var require_cjs4 = __commonJS({
|
|
68809
|
+
"node_modules/@coderifts/agent-guard/dist/cjs/index.js"(exports2) {
|
|
68810
|
+
"use strict";
|
|
68811
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
68812
|
+
exports2.withCodeRifts = exports2.coverageReport = exports2.deployGate = exports2.gateDecision = exports2.RegistryConstructionError = exports2.guardToolRegistry = exports2.globToRegExp = exports2.matchGlob = exports2.classifyByName = exports2.resolveArtifacts = exports2.deriveKeySignal = exports2.pathClass = exports2.classifyCommand = exports2.projectState = exports2.emptySessionState = exports2.computeTainted = exports2.evaluate = exports2.updateSession = exports2.SESSION_TAINT_VERSION = exports2.SessionTaintTracker = exports2.readDecision = exports2.computeBundleFingerprint = exports2.computeArtifactDigest = exports2.evaluateEnvelope = exports2.RECEIPT_PREV_NULL = exports2.decodeReceiptBodyPrev = exports2.previousReceiptCommitment = exports2.verifyReceiptChainLinkage = exports2.canonicalJson = exports2.computeBodyHash = exports2.bindReceiptToEnvelope = exports2.DETECTOR_VERSION = exports2.builtinDetector = exports2.guardToolCall = void 0;
|
|
68813
|
+
var guard_js_1 = require_guard();
|
|
68814
|
+
Object.defineProperty(exports2, "guardToolCall", { enumerable: true, get: function() {
|
|
68815
|
+
return guard_js_1.guardToolCall;
|
|
68816
|
+
} });
|
|
68817
|
+
var detector_js_1 = require_detector();
|
|
68818
|
+
Object.defineProperty(exports2, "builtinDetector", { enumerable: true, get: function() {
|
|
68819
|
+
return detector_js_1.builtinDetector;
|
|
68820
|
+
} });
|
|
68821
|
+
Object.defineProperty(exports2, "DETECTOR_VERSION", { enumerable: true, get: function() {
|
|
68822
|
+
return detector_js_1.DETECTOR_VERSION;
|
|
68823
|
+
} });
|
|
68824
|
+
var receipt_binding_js_1 = require_receipt_binding();
|
|
68825
|
+
Object.defineProperty(exports2, "bindReceiptToEnvelope", { enumerable: true, get: function() {
|
|
68826
|
+
return receipt_binding_js_1.bindReceiptToEnvelope;
|
|
68827
|
+
} });
|
|
68828
|
+
Object.defineProperty(exports2, "computeBodyHash", { enumerable: true, get: function() {
|
|
68829
|
+
return receipt_binding_js_1.computeBodyHash;
|
|
68830
|
+
} });
|
|
68831
|
+
Object.defineProperty(exports2, "canonicalJson", { enumerable: true, get: function() {
|
|
68832
|
+
return receipt_binding_js_1.canonicalJson;
|
|
68833
|
+
} });
|
|
68834
|
+
var receipt_chain_js_1 = require_receipt_chain();
|
|
68835
|
+
Object.defineProperty(exports2, "verifyReceiptChainLinkage", { enumerable: true, get: function() {
|
|
68836
|
+
return receipt_chain_js_1.verifyReceiptChainLinkage;
|
|
68837
|
+
} });
|
|
68838
|
+
Object.defineProperty(exports2, "previousReceiptCommitment", { enumerable: true, get: function() {
|
|
68839
|
+
return receipt_chain_js_1.previousReceiptCommitment;
|
|
68840
|
+
} });
|
|
68841
|
+
Object.defineProperty(exports2, "decodeReceiptBodyPrev", { enumerable: true, get: function() {
|
|
68842
|
+
return receipt_chain_js_1.decodeReceiptBodyPrev;
|
|
68843
|
+
} });
|
|
68844
|
+
Object.defineProperty(exports2, "RECEIPT_PREV_NULL", { enumerable: true, get: function() {
|
|
68845
|
+
return receipt_chain_js_1.RECEIPT_PREV_NULL;
|
|
68846
|
+
} });
|
|
68847
|
+
var enforcement_gate_js_1 = require_enforcement_gate();
|
|
68848
|
+
Object.defineProperty(exports2, "evaluateEnvelope", { enumerable: true, get: function() {
|
|
68849
|
+
return enforcement_gate_js_1.evaluateEnvelope;
|
|
68850
|
+
} });
|
|
68851
|
+
Object.defineProperty(exports2, "computeArtifactDigest", { enumerable: true, get: function() {
|
|
68852
|
+
return enforcement_gate_js_1.computeArtifactDigest;
|
|
68853
|
+
} });
|
|
68854
|
+
Object.defineProperty(exports2, "computeBundleFingerprint", { enumerable: true, get: function() {
|
|
68855
|
+
return enforcement_gate_js_1.computeBundleFingerprint;
|
|
68856
|
+
} });
|
|
68857
|
+
var sdk_1 = require_cjs3();
|
|
68858
|
+
Object.defineProperty(exports2, "readDecision", { enumerable: true, get: function() {
|
|
68859
|
+
return sdk_1.readDecision;
|
|
68860
|
+
} });
|
|
68861
|
+
var session_taint_js_1 = require_session_taint();
|
|
68862
|
+
Object.defineProperty(exports2, "SessionTaintTracker", { enumerable: true, get: function() {
|
|
68863
|
+
return session_taint_js_1.SessionTaintTracker;
|
|
68864
|
+
} });
|
|
68865
|
+
Object.defineProperty(exports2, "SESSION_TAINT_VERSION", { enumerable: true, get: function() {
|
|
68866
|
+
return session_taint_js_1.SESSION_TAINT_VERSION;
|
|
68867
|
+
} });
|
|
68868
|
+
Object.defineProperty(exports2, "updateSession", { enumerable: true, get: function() {
|
|
68869
|
+
return session_taint_js_1.updateSession;
|
|
68870
|
+
} });
|
|
68871
|
+
Object.defineProperty(exports2, "evaluate", { enumerable: true, get: function() {
|
|
68872
|
+
return session_taint_js_1.evaluate;
|
|
68873
|
+
} });
|
|
68874
|
+
Object.defineProperty(exports2, "computeTainted", { enumerable: true, get: function() {
|
|
68875
|
+
return session_taint_js_1.computeTainted;
|
|
68876
|
+
} });
|
|
68877
|
+
Object.defineProperty(exports2, "emptySessionState", { enumerable: true, get: function() {
|
|
68878
|
+
return session_taint_js_1.emptySessionState;
|
|
68879
|
+
} });
|
|
68880
|
+
Object.defineProperty(exports2, "projectState", { enumerable: true, get: function() {
|
|
68881
|
+
return session_taint_js_1.projectState;
|
|
68882
|
+
} });
|
|
68883
|
+
Object.defineProperty(exports2, "classifyCommand", { enumerable: true, get: function() {
|
|
68884
|
+
return session_taint_js_1.classifyCommand;
|
|
68885
|
+
} });
|
|
68886
|
+
Object.defineProperty(exports2, "pathClass", { enumerable: true, get: function() {
|
|
68887
|
+
return session_taint_js_1.pathClass;
|
|
68888
|
+
} });
|
|
68889
|
+
Object.defineProperty(exports2, "deriveKeySignal", { enumerable: true, get: function() {
|
|
68890
|
+
return session_taint_js_1.deriveKeySignal;
|
|
68891
|
+
} });
|
|
68892
|
+
var artifact_resolver_js_1 = require_artifact_resolver();
|
|
68893
|
+
Object.defineProperty(exports2, "resolveArtifacts", { enumerable: true, get: function() {
|
|
68894
|
+
return artifact_resolver_js_1.resolve;
|
|
68895
|
+
} });
|
|
68896
|
+
Object.defineProperty(exports2, "classifyByName", { enumerable: true, get: function() {
|
|
68897
|
+
return artifact_resolver_js_1.classifyByName;
|
|
68898
|
+
} });
|
|
68899
|
+
var resolver_glob_js_1 = require_resolver_glob();
|
|
68900
|
+
Object.defineProperty(exports2, "matchGlob", { enumerable: true, get: function() {
|
|
68901
|
+
return resolver_glob_js_1.matchGlob;
|
|
68902
|
+
} });
|
|
68903
|
+
Object.defineProperty(exports2, "globToRegExp", { enumerable: true, get: function() {
|
|
68904
|
+
return resolver_glob_js_1.globToRegExp;
|
|
68905
|
+
} });
|
|
68906
|
+
var tool_registry_js_1 = require_tool_registry();
|
|
68907
|
+
Object.defineProperty(exports2, "guardToolRegistry", { enumerable: true, get: function() {
|
|
68908
|
+
return tool_registry_js_1.guardToolRegistry;
|
|
68909
|
+
} });
|
|
68910
|
+
Object.defineProperty(exports2, "RegistryConstructionError", { enumerable: true, get: function() {
|
|
68911
|
+
return tool_registry_js_1.RegistryConstructionError;
|
|
68912
|
+
} });
|
|
68913
|
+
var merge_gate_js_1 = require_merge_gate();
|
|
68914
|
+
Object.defineProperty(exports2, "gateDecision", { enumerable: true, get: function() {
|
|
68915
|
+
return merge_gate_js_1.gateDecision;
|
|
68916
|
+
} });
|
|
68917
|
+
var deploy_gate_js_1 = require_deploy_gate();
|
|
68918
|
+
Object.defineProperty(exports2, "deployGate", { enumerable: true, get: function() {
|
|
68919
|
+
return deploy_gate_js_1.deployGate;
|
|
68920
|
+
} });
|
|
68921
|
+
var coverage_report_js_1 = require_coverage_report();
|
|
68922
|
+
Object.defineProperty(exports2, "coverageReport", { enumerable: true, get: function() {
|
|
68923
|
+
return coverage_report_js_1.coverageReport;
|
|
68924
|
+
} });
|
|
68925
|
+
var with_coderifts_js_1 = require_with_coderifts();
|
|
68926
|
+
Object.defineProperty(exports2, "withCodeRifts", { enumerable: true, get: function() {
|
|
68927
|
+
return with_coderifts_js_1.withCodeRifts;
|
|
68928
|
+
} });
|
|
68929
|
+
}
|
|
68930
|
+
});
|
|
68931
|
+
|
|
68932
|
+
// src/commands/deploy-gate.js
|
|
68933
|
+
var require_deploy_gate2 = __commonJS({
|
|
68934
|
+
"src/commands/deploy-gate.js"(exports2, module2) {
|
|
68935
|
+
"use strict";
|
|
68936
|
+
var fs = require("fs");
|
|
68937
|
+
var path = require("path");
|
|
68938
|
+
var chalk = require_source();
|
|
68939
|
+
var { deployGate } = require_cjs4();
|
|
68940
|
+
var { renderJson } = require_json2();
|
|
68941
|
+
if (process.env.NO_COLOR) chalk.level = 0;
|
|
68942
|
+
var REPAIRABLE = /* @__PURE__ */ new Set(["env_mismatch", "stale_artifact", "operation_mismatch", "receipt_not_authorized", "fingerprint_mismatch", "body_hash_mismatch"]);
|
|
68943
|
+
function enforceSignal(options) {
|
|
68944
|
+
return options && options.enforce === true || String(process.env.CODERIFTS_DEPLOY_ENFORCE || "").toLowerCase() === "true";
|
|
68945
|
+
}
|
|
68946
|
+
function observeCDEnforcement(options = {}) {
|
|
68947
|
+
const envVal = String(process.env.CODERIFTS_DEPLOY_ENFORCE || "").toLowerCase();
|
|
68948
|
+
let enforcement;
|
|
68949
|
+
if (enforceSignal(options)) enforcement = "ENFORCING";
|
|
68950
|
+
else if (envVal === "unknown") enforcement = "UNKNOWN";
|
|
68951
|
+
else enforcement = "ADVISORY";
|
|
68952
|
+
const bypass_possible = String(process.env.CODERIFTS_DEPLOY_NO_BYPASS || "").toLowerCase() !== "true";
|
|
68953
|
+
return {
|
|
68954
|
+
enforcement,
|
|
68955
|
+
bypass_possible,
|
|
68956
|
+
step_is_required: enforcement === "ENFORCING",
|
|
68957
|
+
required_step_name: "CodeRifts / deploy-gate",
|
|
68958
|
+
attestation_source: "cli_flag"
|
|
68959
|
+
};
|
|
68960
|
+
}
|
|
68961
|
+
function deployReportResiduals(state, inescapable, enforcement) {
|
|
68962
|
+
const out = [];
|
|
68963
|
+
if (state === "success" && inescapable !== true) {
|
|
68964
|
+
if (enforcement === "ENFORCING") out.push("bypass_open");
|
|
68965
|
+
else if (enforcement === "ADVISORY") out.push("deploy_gate_advisory");
|
|
68966
|
+
else if (enforcement === "ABSENT") out.push("deploy_path_ungated");
|
|
68967
|
+
}
|
|
68968
|
+
return out;
|
|
68969
|
+
}
|
|
68970
|
+
function deployCoverageInput(enforcement_state, inescapable_deploy) {
|
|
68971
|
+
return { enforcement_state, inescapable_deploy: inescapable_deploy === true, applicability_attested: true };
|
|
68972
|
+
}
|
|
68973
|
+
function deployBind({ environment, artifact_id, receipt, observed_cd_enforcement, expected_fingerprint, expected_body_hash }) {
|
|
68974
|
+
const attested_enforcement = observed_cd_enforcement && observed_cd_enforcement.enforcement || "UNKNOWN";
|
|
68975
|
+
if (!receipt) {
|
|
68976
|
+
return {
|
|
68977
|
+
deploy_check_status: "pending",
|
|
68978
|
+
reason: "no_receipt",
|
|
68979
|
+
must_re_preflight: true,
|
|
68980
|
+
attested_enforcement,
|
|
68981
|
+
gate: null,
|
|
68982
|
+
report_residuals: [],
|
|
68983
|
+
coverage_deploy_input: deployCoverageInput(attested_enforcement, false)
|
|
68984
|
+
};
|
|
68985
|
+
}
|
|
68986
|
+
const requiredContext = {
|
|
68987
|
+
operation: "deploy",
|
|
68988
|
+
enforcement: {
|
|
68989
|
+
enforcement: attested_enforcement,
|
|
68990
|
+
// fail-closed: bypass is possible unless observation proved it disabled.
|
|
68991
|
+
bypass_possible: !(observed_cd_enforcement && observed_cd_enforcement.bypass_possible === false)
|
|
68992
|
+
}
|
|
68993
|
+
};
|
|
68994
|
+
if (attested_enforcement === "ENFORCING") {
|
|
68995
|
+
if (expected_fingerprint != null) requiredContext.expected_fingerprint = expected_fingerprint;
|
|
68996
|
+
if (expected_body_hash != null) requiredContext.expected_body_hash = expected_body_hash;
|
|
68997
|
+
}
|
|
68998
|
+
const gate = deployGate({ deployTarget: { environment, artifact_id }, receipt, requiredContext });
|
|
68999
|
+
const inescapable_deploy = gate.inescapable_deploy === true;
|
|
69000
|
+
return {
|
|
69001
|
+
deploy_check_status: gate.state,
|
|
69002
|
+
reason: gate.reason,
|
|
69003
|
+
must_re_preflight: REPAIRABLE.has(gate.reason),
|
|
69004
|
+
attested_enforcement,
|
|
69005
|
+
gate: { deploy_allowed: gate.deploy_allowed, reason: gate.reason, inescapable_deploy },
|
|
69006
|
+
report_residuals: deployReportResiduals(gate.state, inescapable_deploy, attested_enforcement),
|
|
69007
|
+
coverage_deploy_input: deployCoverageInput(attested_enforcement, inescapable_deploy)
|
|
69008
|
+
};
|
|
69009
|
+
}
|
|
69010
|
+
function clampExit(deployCheckStatus, enforce) {
|
|
69011
|
+
if (deployCheckStatus === "success") return 0;
|
|
69012
|
+
if (deployCheckStatus === "failure" && enforce === true) return 1;
|
|
69013
|
+
return 0;
|
|
69014
|
+
}
|
|
69015
|
+
function readReceiptFile(filePath) {
|
|
69016
|
+
if (!filePath) return null;
|
|
69017
|
+
const resolved = path.resolve(filePath);
|
|
69018
|
+
if (!fs.existsSync(resolved)) return null;
|
|
69019
|
+
try {
|
|
69020
|
+
return JSON.parse(fs.readFileSync(resolved, "utf-8"));
|
|
69021
|
+
} catch (_) {
|
|
69022
|
+
return null;
|
|
69023
|
+
}
|
|
69024
|
+
}
|
|
69025
|
+
function renderDeployGateTerminal(bind, enforce) {
|
|
69026
|
+
const g = bind.gate;
|
|
69027
|
+
const color = bind.deploy_check_status === "success" ? chalk.green : bind.deploy_check_status === "failure" ? chalk.red : chalk.yellow;
|
|
69028
|
+
const lines = [];
|
|
69029
|
+
lines.push("");
|
|
69030
|
+
lines.push(chalk.bold(` CodeRifts deploy-gate \u2014 ${color(bind.deploy_check_status.toUpperCase())}`));
|
|
69031
|
+
lines.push(` Reason: ${bind.reason}`);
|
|
69032
|
+
lines.push(` Enforcement: ${bind.attested_enforcement}`);
|
|
69033
|
+
lines.push(` inescapable_deploy: ${g ? g.inescapable_deploy : false}`);
|
|
69034
|
+
if (bind.report_residuals.length) lines.push(` Residuals: ${bind.report_residuals.join(", ")}`);
|
|
69035
|
+
if (bind.must_re_preflight) lines.push(chalk.yellow(" Action: re-preflight this { environment, artifact } \u2014 the receipt does not authorize it."));
|
|
69036
|
+
lines.push("");
|
|
69037
|
+
lines.push(enforce ? chalk.dim(" Enforcing \u2014 a failing gate exits non-zero (blocks the deploy step).") : chalk.dim(" Advisory (phase 1) \u2014 does not block the deploy (exit 0)."));
|
|
69038
|
+
lines.push("");
|
|
69039
|
+
return lines.join("\n");
|
|
69040
|
+
}
|
|
69041
|
+
async function runDeployGate(options = {}) {
|
|
69042
|
+
const environment = options.env;
|
|
69043
|
+
const artifactId = options.artifact;
|
|
69044
|
+
if (!environment || !artifactId) {
|
|
69045
|
+
console.error(chalk.red("Error: --env and --artifact are required."));
|
|
69046
|
+
process.exit(1);
|
|
69047
|
+
return;
|
|
69048
|
+
}
|
|
69049
|
+
const enforce = enforceSignal(options);
|
|
69050
|
+
const receipt = readReceiptFile(options.receipt);
|
|
69051
|
+
const observed = observeCDEnforcement({ enforce });
|
|
69052
|
+
const bind = deployBind({ environment, artifact_id: artifactId, receipt, observed_cd_enforcement: observed });
|
|
69053
|
+
const code = clampExit(bind.deploy_check_status, enforce);
|
|
69054
|
+
if (options.json) {
|
|
69055
|
+
console.log(renderJson({ command: "deploy-gate", environment, artifact_id: artifactId, phase: enforce ? "enforcing" : "advisory", exit_code: code, ...bind }));
|
|
69056
|
+
} else {
|
|
69057
|
+
console.log(renderDeployGateTerminal(bind, enforce));
|
|
69058
|
+
}
|
|
69059
|
+
process.exit(code);
|
|
69060
|
+
}
|
|
69061
|
+
module2.exports = {
|
|
69062
|
+
runDeployGate,
|
|
69063
|
+
deployBind,
|
|
69064
|
+
observeCDEnforcement,
|
|
69065
|
+
clampExit,
|
|
69066
|
+
readReceiptFile,
|
|
69067
|
+
renderDeployGateTerminal
|
|
69068
|
+
};
|
|
69069
|
+
}
|
|
69070
|
+
});
|
|
69071
|
+
|
|
69072
|
+
// src/commands/publish-gate.js
|
|
69073
|
+
var require_publish_gate = __commonJS({
|
|
69074
|
+
"src/commands/publish-gate.js"(exports2, module2) {
|
|
69075
|
+
"use strict";
|
|
69076
|
+
var fs = require("fs");
|
|
69077
|
+
var path = require("path");
|
|
69078
|
+
var { execFileSync } = require("child_process");
|
|
69079
|
+
var chalk = require_source();
|
|
69080
|
+
var { getApiKey } = require_config();
|
|
69081
|
+
var { cloudDiff } = require_cloud();
|
|
69082
|
+
if (process.env.NO_COLOR) chalk.level = 0;
|
|
69083
|
+
var ZERO_SHA = "0000000000000000000000000000000000000000";
|
|
69084
|
+
var CLOSED_ACTIONS = /* @__PURE__ */ new Set([
|
|
69085
|
+
"CONTINUE",
|
|
69086
|
+
"CONTINUE_WITH_MONITORING",
|
|
69087
|
+
"REQUEST_APPROVAL",
|
|
69088
|
+
"STOP"
|
|
69089
|
+
]);
|
|
69090
|
+
var PERMIT_ACTIONS = /* @__PURE__ */ new Set(["CONTINUE", "CONTINUE_WITH_MONITORING"]);
|
|
69091
|
+
function defaultGit(args, cwd) {
|
|
69092
|
+
return execFileSync("git", args, {
|
|
69093
|
+
cwd: cwd || process.cwd(),
|
|
69094
|
+
encoding: "utf8",
|
|
69095
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
69096
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
69097
|
+
}).trim();
|
|
69098
|
+
}
|
|
69099
|
+
function gitShow(ref, filePath, { gitImpl = defaultGit, cwd } = {}) {
|
|
69100
|
+
try {
|
|
69101
|
+
const out = gitImpl(["show", `${ref}:${filePath}`], cwd);
|
|
69102
|
+
return { ok: true, content: out == null ? "" : String(out) };
|
|
69103
|
+
} catch (err) {
|
|
69104
|
+
const msg = err && err.stderr ? String(err.stderr) : err && err.message || String(err);
|
|
69105
|
+
return {
|
|
69106
|
+
ok: false,
|
|
69107
|
+
code: "GIT_ERROR",
|
|
69108
|
+
message: `git error reading ${ref}:${filePath}: ${msg.slice(0, 300)}`
|
|
69109
|
+
};
|
|
69110
|
+
}
|
|
69111
|
+
}
|
|
69112
|
+
function readPackageVersion(cwd, readFile = fs.readFileSync) {
|
|
69113
|
+
const pkgPath = path.join(cwd || process.cwd(), "package.json");
|
|
69114
|
+
try {
|
|
69115
|
+
const raw = readFile(pkgPath, "utf8");
|
|
69116
|
+
const pkg2 = JSON.parse(raw);
|
|
69117
|
+
return pkg2 && typeof pkg2.version === "string" ? pkg2.version : null;
|
|
69118
|
+
} catch {
|
|
69119
|
+
return null;
|
|
69120
|
+
}
|
|
69121
|
+
}
|
|
69122
|
+
function resolveBeforeSpec(specPath, {
|
|
69123
|
+
gitImpl = defaultGit,
|
|
69124
|
+
cwd = process.cwd(),
|
|
69125
|
+
readFile = fs.readFileSync,
|
|
69126
|
+
packageVersion = null
|
|
69127
|
+
} = {}) {
|
|
69128
|
+
const version = packageVersion != null ? packageVersion : readPackageVersion(cwd, readFile);
|
|
69129
|
+
const tried = [];
|
|
69130
|
+
if (version) {
|
|
69131
|
+
const tags = [`v${version}`, version];
|
|
69132
|
+
for (const tag of tags) {
|
|
69133
|
+
tried.push(`tag:${tag}`);
|
|
69134
|
+
try {
|
|
69135
|
+
gitImpl(["rev-parse", "--verify", `${tag}^{commit}`], cwd);
|
|
69136
|
+
} catch {
|
|
69137
|
+
continue;
|
|
69138
|
+
}
|
|
69139
|
+
const shown = gitShow(tag, specPath, { gitImpl, cwd });
|
|
69140
|
+
if (!shown.ok) {
|
|
69141
|
+
return {
|
|
69142
|
+
ok: false,
|
|
69143
|
+
code: shown.code || "GIT_ERROR",
|
|
69144
|
+
message: shown.message,
|
|
69145
|
+
tried
|
|
69146
|
+
};
|
|
69147
|
+
}
|
|
69148
|
+
if (shown.content.trim() === "") {
|
|
69149
|
+
return {
|
|
69150
|
+
ok: false,
|
|
69151
|
+
code: "EMPTY_BEFORE",
|
|
69152
|
+
message: `Empty contract artifact at tag ${tag}:${specPath}. Refusing to treat empty before as NEW_ARTIFACT (would false-pass enforce).`,
|
|
69153
|
+
tried
|
|
69154
|
+
};
|
|
69155
|
+
}
|
|
69156
|
+
return { ok: true, content: shown.content, source: `tag:${tag}`, tried };
|
|
69157
|
+
}
|
|
69158
|
+
} else {
|
|
69159
|
+
tried.push("package.json:version (missing)");
|
|
69160
|
+
}
|
|
69161
|
+
const bases = ["origin/main", "origin/master", "main", "master"];
|
|
69162
|
+
for (const base of bases) {
|
|
69163
|
+
tried.push(`merge-base:${base}`);
|
|
69164
|
+
let mb;
|
|
69165
|
+
try {
|
|
69166
|
+
mb = gitImpl(["merge-base", "HEAD", base], cwd);
|
|
69167
|
+
} catch {
|
|
69168
|
+
continue;
|
|
69169
|
+
}
|
|
69170
|
+
if (!mb || mb === ZERO_SHA) continue;
|
|
69171
|
+
const shown = gitShow(mb, specPath, { gitImpl, cwd });
|
|
69172
|
+
if (!shown.ok) {
|
|
69173
|
+
return {
|
|
69174
|
+
ok: false,
|
|
69175
|
+
code: shown.code || "GIT_ERROR",
|
|
69176
|
+
message: shown.message,
|
|
69177
|
+
tried
|
|
69178
|
+
};
|
|
69179
|
+
}
|
|
69180
|
+
if (shown.content.trim() === "") {
|
|
69181
|
+
return {
|
|
69182
|
+
ok: false,
|
|
69183
|
+
code: "EMPTY_BEFORE",
|
|
69184
|
+
message: `Empty contract artifact at merge-base ${mb}:${specPath} (${base}). Refusing to treat empty before as NEW_ARTIFACT (would false-pass enforce).`,
|
|
69185
|
+
tried
|
|
69186
|
+
};
|
|
69187
|
+
}
|
|
69188
|
+
return {
|
|
69189
|
+
ok: true,
|
|
69190
|
+
content: shown.content,
|
|
69191
|
+
source: `merge-base:${base}@${mb.slice(0, 12)}`,
|
|
69192
|
+
tried
|
|
69193
|
+
};
|
|
69194
|
+
}
|
|
69195
|
+
return {
|
|
69196
|
+
ok: false,
|
|
69197
|
+
code: "BEFORE_UNRESOLVED",
|
|
69198
|
+
message: `Could not resolve a non-empty before-spec for ${specPath}. Tried: (a) git tag of package.json version, (b) merge-base with origin/main. Attempts: ${tried.join(", ")}. Fail-closed \u2014 will not publish without a baseline.`,
|
|
69199
|
+
tried
|
|
69200
|
+
};
|
|
69201
|
+
}
|
|
69202
|
+
function resolveAfterSpec(specPath, {
|
|
69203
|
+
cwd = process.cwd(),
|
|
69204
|
+
readFile = fs.readFileSync,
|
|
69205
|
+
exists = fs.existsSync
|
|
69206
|
+
} = {}) {
|
|
69207
|
+
const resolved = path.isAbsolute(specPath) ? specPath : path.join(cwd, specPath);
|
|
69208
|
+
try {
|
|
69209
|
+
if (!exists(resolved)) {
|
|
69210
|
+
return {
|
|
69211
|
+
ok: false,
|
|
69212
|
+
code: "AFTER_MISSING",
|
|
69213
|
+
message: `Working-tree contract artifact not found: ${specPath}`
|
|
69214
|
+
};
|
|
69215
|
+
}
|
|
69216
|
+
const content = readFile(resolved, "utf8");
|
|
69217
|
+
if (content == null || String(content).trim() === "") {
|
|
69218
|
+
return {
|
|
69219
|
+
ok: false,
|
|
69220
|
+
code: "AFTER_EMPTY",
|
|
69221
|
+
message: `Working-tree contract artifact is empty: ${specPath}`
|
|
69222
|
+
};
|
|
69223
|
+
}
|
|
69224
|
+
return { ok: true, content: String(content), path: resolved };
|
|
69225
|
+
} catch (err) {
|
|
69226
|
+
return {
|
|
69227
|
+
ok: false,
|
|
69228
|
+
code: "AFTER_READ_ERROR",
|
|
69229
|
+
message: `Failed to read working-tree ${specPath}: ${err && err.message}`
|
|
69230
|
+
};
|
|
69231
|
+
}
|
|
69232
|
+
}
|
|
69233
|
+
function evaluatePublishPermission(result) {
|
|
69234
|
+
if (!result || typeof result !== "object") {
|
|
69235
|
+
return {
|
|
69236
|
+
allow: false,
|
|
69237
|
+
execution_action: null,
|
|
69238
|
+
decision: null,
|
|
69239
|
+
policy: "fail_closed:unreadable_response"
|
|
69240
|
+
};
|
|
69241
|
+
}
|
|
69242
|
+
const env = result.decision_result && typeof result.decision_result === "object" ? result.decision_result : null;
|
|
69243
|
+
let ea = null;
|
|
69244
|
+
if (env && typeof env.execution_action === "string") ea = env.execution_action;
|
|
69245
|
+
else if (typeof result.execution_action === "string") ea = result.execution_action;
|
|
69246
|
+
const decision = env && env.decision || result.decision || result.omega_decision || null;
|
|
69247
|
+
if (ea && CLOSED_ACTIONS.has(ea)) {
|
|
69248
|
+
const allow = PERMIT_ACTIONS.has(ea);
|
|
69249
|
+
return {
|
|
69250
|
+
allow,
|
|
69251
|
+
execution_action: ea,
|
|
69252
|
+
decision: decision || null,
|
|
69253
|
+
policy: allow ? `permit:execution_action=${ea}` : `block:execution_action=${ea}`
|
|
69254
|
+
};
|
|
69255
|
+
}
|
|
69256
|
+
if (ea != null && ea !== "" && !CLOSED_ACTIONS.has(ea)) {
|
|
69257
|
+
return {
|
|
69258
|
+
allow: false,
|
|
69259
|
+
execution_action: ea,
|
|
69260
|
+
decision: decision || null,
|
|
69261
|
+
policy: `block:unrecognised_execution_action=${ea}`
|
|
69262
|
+
};
|
|
69263
|
+
}
|
|
69264
|
+
if (decision === "BLOCK" || decision === "REQUIRE_APPROVAL") {
|
|
69265
|
+
return {
|
|
69266
|
+
allow: false,
|
|
69267
|
+
execution_action: null,
|
|
69268
|
+
decision,
|
|
69269
|
+
policy: `block:decision=${decision}`
|
|
69270
|
+
};
|
|
69271
|
+
}
|
|
69272
|
+
if (decision === "ALLOW" || decision === "WARN" || decision === "PASS") {
|
|
69273
|
+
return {
|
|
69274
|
+
allow: true,
|
|
69275
|
+
execution_action: null,
|
|
69276
|
+
decision,
|
|
69277
|
+
policy: `permit:decision=${decision}`
|
|
69278
|
+
};
|
|
69279
|
+
}
|
|
69280
|
+
const omega = result.omega_decision;
|
|
69281
|
+
if (omega === "BLOCK" || omega === "REQUIRE_APPROVAL") {
|
|
69282
|
+
return {
|
|
69283
|
+
allow: false,
|
|
69284
|
+
execution_action: null,
|
|
69285
|
+
decision: omega,
|
|
69286
|
+
policy: `block:omega_decision=${omega}`
|
|
69287
|
+
};
|
|
69288
|
+
}
|
|
69289
|
+
return {
|
|
69290
|
+
allow: false,
|
|
69291
|
+
execution_action: ea,
|
|
69292
|
+
decision: decision || omega || null,
|
|
69293
|
+
policy: "fail_closed:no_permission_signal"
|
|
69294
|
+
};
|
|
69295
|
+
}
|
|
69296
|
+
function extractReceiptRef(result) {
|
|
69297
|
+
if (!result || typeof result !== "object") return null;
|
|
69298
|
+
const env = result.decision_result;
|
|
69299
|
+
if (env && env.receipt && typeof env.receipt.token === "string") {
|
|
69300
|
+
return env.receipt.token.slice(0, 24) + (env.receipt.token.length > 24 ? "\u2026" : "");
|
|
69301
|
+
}
|
|
69302
|
+
if (env && typeof env.decision_id === "string") return env.decision_id;
|
|
69303
|
+
if (typeof result.decision_id === "string") return result.decision_id;
|
|
69304
|
+
if (typeof result.fingerprint === "string") return result.fingerprint;
|
|
69305
|
+
if (env && typeof env.fingerprint === "string") return env.fingerprint;
|
|
69306
|
+
return null;
|
|
69307
|
+
}
|
|
69308
|
+
async function defaultPreflight(before, after, { apiKey } = {}) {
|
|
69309
|
+
const key = process.env.CODERIFTS_FORCE_LOCAL_PREFLIGHT ? null : apiKey != null ? apiKey : getApiKey();
|
|
69310
|
+
if (key) {
|
|
69311
|
+
return cloudDiff(before, after, key);
|
|
69312
|
+
}
|
|
69313
|
+
const yaml = require_js_yaml();
|
|
69314
|
+
const { diffSpecs } = require_api2();
|
|
69315
|
+
let oldSpec;
|
|
69316
|
+
let newSpec;
|
|
69317
|
+
try {
|
|
69318
|
+
oldSpec = yaml.load(before);
|
|
69319
|
+
newSpec = yaml.load(after);
|
|
69320
|
+
} catch (e) {
|
|
69321
|
+
const err = new Error(`Failed to parse specs: ${e.message}`);
|
|
69322
|
+
err.code = "PREFLIGHT_UNREACHABLE";
|
|
69323
|
+
throw err;
|
|
69324
|
+
}
|
|
69325
|
+
let diffResult;
|
|
69326
|
+
try {
|
|
69327
|
+
diffResult = await diffSpecs({
|
|
69328
|
+
sourceSpec: { content: JSON.stringify(oldSpec), location: "before.json", format: "openapi3" },
|
|
69329
|
+
destinationSpec: { content: JSON.stringify(newSpec), location: "after.json", format: "openapi3" }
|
|
69330
|
+
});
|
|
69331
|
+
} catch (e) {
|
|
69332
|
+
const err = new Error(`Local preflight engine error: ${e.message}`);
|
|
69333
|
+
err.code = "PREFLIGHT_UNREACHABLE";
|
|
69334
|
+
throw err;
|
|
69335
|
+
}
|
|
69336
|
+
const breaking = (diffResult.breakingDifferences || []).length;
|
|
69337
|
+
const decision = breaking > 0 ? "BLOCK" : "ALLOW";
|
|
69338
|
+
const execution_action = breaking > 0 ? "STOP" : "CONTINUE";
|
|
69339
|
+
return {
|
|
69340
|
+
decision,
|
|
69341
|
+
omega_decision: decision,
|
|
69342
|
+
execution_action,
|
|
69343
|
+
decision_result: {
|
|
69344
|
+
decision,
|
|
69345
|
+
execution_action,
|
|
69346
|
+
decision_id: `local-${Date.now()}`
|
|
69347
|
+
},
|
|
69348
|
+
breaking_changes: diffResult.breakingDifferences || [],
|
|
69349
|
+
risk_score: Math.min(breaking * 15, 100)
|
|
69350
|
+
};
|
|
69351
|
+
}
|
|
69352
|
+
async function runPublishGate(options = {}, deps = {}) {
|
|
69353
|
+
const cwd = deps.cwd || process.cwd();
|
|
69354
|
+
const gitImpl = deps.gitImpl || defaultGit;
|
|
69355
|
+
const readFile = deps.readFile || fs.readFileSync.bind(fs);
|
|
69356
|
+
const exists = deps.exists || fs.existsSync.bind(fs);
|
|
69357
|
+
const preflightFn = deps.preflightFn || defaultPreflight;
|
|
69358
|
+
const log = deps.log || console.log.bind(console);
|
|
69359
|
+
const logErr = deps.logErr || console.error.bind(console);
|
|
69360
|
+
let specPath = options.spec;
|
|
69361
|
+
if (!specPath) {
|
|
69362
|
+
try {
|
|
69363
|
+
specPath = gitImpl(["config", "coderifts.specPath"], cwd);
|
|
69364
|
+
} catch {
|
|
69365
|
+
specPath = "";
|
|
69366
|
+
}
|
|
69367
|
+
}
|
|
69368
|
+
if (!specPath) specPath = "api/openapi.yaml";
|
|
69369
|
+
try {
|
|
69370
|
+
gitImpl(["rev-parse", "--is-inside-work-tree"], cwd);
|
|
69371
|
+
} catch (err) {
|
|
69372
|
+
const msg = "CodeRifts publish-gate: GIT_ERROR \u2014 not a git repository (or git unavailable). Cannot resolve before-spec without git. Fail-closed.";
|
|
69373
|
+
logErr(chalk.red(msg));
|
|
69374
|
+
return finish({
|
|
69375
|
+
ok: false,
|
|
69376
|
+
exitCode: 1,
|
|
69377
|
+
code: "GIT_ERROR",
|
|
69378
|
+
message: msg,
|
|
69379
|
+
policy: "fail_closed:git_error"
|
|
69380
|
+
}, { log, json: options.json });
|
|
69381
|
+
}
|
|
69382
|
+
const beforeRes = resolveBeforeSpec(specPath, {
|
|
69383
|
+
gitImpl,
|
|
69384
|
+
cwd,
|
|
69385
|
+
readFile,
|
|
69386
|
+
packageVersion: deps.packageVersion
|
|
69387
|
+
});
|
|
69388
|
+
if (!beforeRes.ok) {
|
|
69389
|
+
logErr(chalk.red(`CodeRifts publish-gate: ${beforeRes.code} \u2014 ${beforeRes.message}`));
|
|
69390
|
+
return finish({
|
|
69391
|
+
ok: false,
|
|
69392
|
+
exitCode: 1,
|
|
69393
|
+
code: beforeRes.code,
|
|
69394
|
+
message: beforeRes.message,
|
|
69395
|
+
policy: `fail_closed:${beforeRes.code}`,
|
|
69396
|
+
tried: beforeRes.tried
|
|
69397
|
+
}, { log, json: options.json });
|
|
69398
|
+
}
|
|
69399
|
+
const afterRes = resolveAfterSpec(specPath, { cwd, readFile, exists });
|
|
69400
|
+
if (!afterRes.ok) {
|
|
69401
|
+
logErr(chalk.red(`CodeRifts publish-gate: ${afterRes.code} \u2014 ${afterRes.message}`));
|
|
69402
|
+
return finish({
|
|
69403
|
+
ok: false,
|
|
69404
|
+
exitCode: 1,
|
|
69405
|
+
code: afterRes.code,
|
|
69406
|
+
message: afterRes.message,
|
|
69407
|
+
policy: `fail_closed:${afterRes.code}`
|
|
69408
|
+
}, { log, json: options.json });
|
|
69409
|
+
}
|
|
69410
|
+
if (beforeRes.content === afterRes.content) {
|
|
69411
|
+
const payload2 = {
|
|
69412
|
+
ok: true,
|
|
69413
|
+
exitCode: 0,
|
|
69414
|
+
code: "UNCHANGED",
|
|
69415
|
+
message: "Contract artifact unchanged vs baseline; publish permitted.",
|
|
69416
|
+
policy: "permit:unchanged",
|
|
69417
|
+
before_source: beforeRes.source,
|
|
69418
|
+
execution_action: "CONTINUE",
|
|
69419
|
+
receipt: null
|
|
69420
|
+
};
|
|
69421
|
+
if (!options.json) {
|
|
69422
|
+
log(chalk.green("CodeRifts publish-gate: ALLOW (unchanged)"));
|
|
69423
|
+
log(` baseline: ${beforeRes.source}`);
|
|
69424
|
+
log(` spec: ${specPath}`);
|
|
69425
|
+
}
|
|
69426
|
+
return finish(payload2, { log, json: options.json });
|
|
69427
|
+
}
|
|
69428
|
+
let result;
|
|
69429
|
+
try {
|
|
69430
|
+
result = await preflightFn(beforeRes.content, afterRes.content, {
|
|
69431
|
+
apiKey: deps.apiKey,
|
|
69432
|
+
cwd
|
|
69433
|
+
});
|
|
69434
|
+
} catch (err) {
|
|
69435
|
+
const msg = `CodeRifts publish-gate: PREFLIGHT_UNREACHABLE \u2014 ${err && err.message}`;
|
|
69436
|
+
logErr(chalk.red(msg));
|
|
69437
|
+
return finish({
|
|
69438
|
+
ok: false,
|
|
69439
|
+
exitCode: 1,
|
|
69440
|
+
code: "PREFLIGHT_UNREACHABLE",
|
|
69441
|
+
message: msg,
|
|
69442
|
+
policy: "fail_closed:preflight_unreachable"
|
|
69443
|
+
}, { log, json: options.json });
|
|
69444
|
+
}
|
|
69445
|
+
const perm = evaluatePublishPermission(result);
|
|
69446
|
+
const receipt = extractReceiptRef(result);
|
|
69447
|
+
if (!perm.allow) {
|
|
69448
|
+
const payload2 = {
|
|
69449
|
+
ok: false,
|
|
69450
|
+
exitCode: 1,
|
|
69451
|
+
code: "BLOCK",
|
|
69452
|
+
message: "Publish not permitted by execution_action / decision.",
|
|
69453
|
+
policy: perm.policy,
|
|
69454
|
+
execution_action: perm.execution_action,
|
|
69455
|
+
decision: perm.decision,
|
|
69456
|
+
before_source: beforeRes.source,
|
|
69457
|
+
receipt,
|
|
69458
|
+
fail_policy: "exit_1_on_block_or_resolver_error_or_unreachable"
|
|
69459
|
+
};
|
|
69460
|
+
if (!options.json) {
|
|
69461
|
+
logErr("");
|
|
69462
|
+
logErr(chalk.red("========================================"));
|
|
69463
|
+
logErr(chalk.red(" CodeRifts: PUBLISH BLOCKED"));
|
|
69464
|
+
logErr(chalk.red("========================================"));
|
|
69465
|
+
logErr(` Policy: ${perm.policy}`);
|
|
69466
|
+
logErr(` execution_action: ${perm.execution_action || "(none)"}`);
|
|
69467
|
+
logErr(` decision: ${perm.decision || "(none)"}`);
|
|
69468
|
+
logErr(` baseline: ${beforeRes.source}`);
|
|
69469
|
+
logErr(` fail policy: exit 1 on BLOCK / resolver error / preflight unreachability`);
|
|
69470
|
+
logErr(chalk.red("========================================"));
|
|
69471
|
+
logErr("");
|
|
69472
|
+
}
|
|
69473
|
+
return finish(payload2, { log, json: options.json });
|
|
69474
|
+
}
|
|
69475
|
+
const payload = {
|
|
69476
|
+
ok: true,
|
|
69477
|
+
exitCode: 0,
|
|
69478
|
+
code: "ALLOW",
|
|
69479
|
+
message: "Publish permitted.",
|
|
69480
|
+
policy: perm.policy,
|
|
69481
|
+
execution_action: perm.execution_action,
|
|
69482
|
+
decision: perm.decision,
|
|
69483
|
+
before_source: beforeRes.source,
|
|
69484
|
+
receipt
|
|
69485
|
+
};
|
|
69486
|
+
if (!options.json) {
|
|
69487
|
+
log(chalk.green("CodeRifts publish-gate: ALLOW"));
|
|
69488
|
+
log(` Policy: ${perm.policy}`);
|
|
69489
|
+
log(` execution_action: ${perm.execution_action || "(mapped from decision)"}`);
|
|
69490
|
+
log(` baseline: ${beforeRes.source}`);
|
|
69491
|
+
if (receipt) log(` Receipt reference: ${receipt}`);
|
|
69492
|
+
else log(" Receipt reference: (none issued on this path)");
|
|
69493
|
+
}
|
|
69494
|
+
return finish(payload, { log, json: options.json });
|
|
69495
|
+
}
|
|
69496
|
+
function finish(payload, { log, json }) {
|
|
69497
|
+
if (json) {
|
|
69498
|
+
log(JSON.stringify(payload, null, 2));
|
|
69499
|
+
}
|
|
69500
|
+
return payload;
|
|
69501
|
+
}
|
|
69502
|
+
module2.exports = {
|
|
69503
|
+
runPublishGate,
|
|
69504
|
+
resolveBeforeSpec,
|
|
69505
|
+
resolveAfterSpec,
|
|
69506
|
+
evaluatePublishPermission,
|
|
69507
|
+
extractReceiptRef,
|
|
69508
|
+
gitShow,
|
|
69509
|
+
defaultGit,
|
|
69510
|
+
PERMIT_ACTIONS,
|
|
69511
|
+
CLOSED_ACTIONS
|
|
69512
|
+
};
|
|
69513
|
+
}
|
|
69514
|
+
});
|
|
69515
|
+
|
|
65408
69516
|
// src/commands/init.js
|
|
65409
69517
|
var require_init = __commonJS({
|
|
65410
69518
|
"src/commands/init.js"(exports2, module2) {
|
|
@@ -76068,7 +80176,7 @@ var require_zipWith = __commonJS({
|
|
|
76068
80176
|
});
|
|
76069
80177
|
|
|
76070
80178
|
// node_modules/rxjs/dist/cjs/index.js
|
|
76071
|
-
var
|
|
80179
|
+
var require_cjs5 = __commonJS({
|
|
76072
80180
|
"node_modules/rxjs/dist/cjs/index.js"(exports2) {
|
|
76073
80181
|
"use strict";
|
|
76074
80182
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -77385,7 +81493,7 @@ var require_run_async = __commonJS({
|
|
|
77385
81493
|
var require_utils3 = __commonJS({
|
|
77386
81494
|
"node_modules/inquirer/lib/utils/utils.js"(exports2) {
|
|
77387
81495
|
"use strict";
|
|
77388
|
-
var { from, of } =
|
|
81496
|
+
var { from, of } = require_cjs5();
|
|
77389
81497
|
var runAsync = require_run_async();
|
|
77390
81498
|
exports2.fetchAsyncQuestionProperty = function(question, prop, answers) {
|
|
77391
81499
|
if (typeof question[prop] !== "function") {
|
|
@@ -77410,7 +81518,7 @@ var require_prompt = __commonJS({
|
|
|
77410
81518
|
get: require_get2(),
|
|
77411
81519
|
set: require_set3()
|
|
77412
81520
|
};
|
|
77413
|
-
var { defer, empty, from, of } =
|
|
81521
|
+
var { defer, empty, from, of } = require_cjs5();
|
|
77414
81522
|
var { concatMap, filter, publish, reduce } = require_operators();
|
|
77415
81523
|
var runAsync = require_run_async();
|
|
77416
81524
|
var utils = require_utils3();
|
|
@@ -80124,7 +84232,7 @@ var require_base = __commonJS({
|
|
|
80124
84232
|
var require_events = __commonJS({
|
|
80125
84233
|
"node_modules/inquirer/lib/utils/events.js"(exports2, module2) {
|
|
80126
84234
|
"use strict";
|
|
80127
|
-
var { fromEvent } =
|
|
84235
|
+
var { fromEvent } = require_cjs5();
|
|
80128
84236
|
var { filter, map, share, takeUntil } = require_operators();
|
|
80129
84237
|
function normalizeKeypressEvents(value, key) {
|
|
80130
84238
|
return { value, key: key || {} };
|
|
@@ -90922,7 +95030,7 @@ var require_editor = __commonJS({
|
|
|
90922
95030
|
var { editAsync } = require_commonjs();
|
|
90923
95031
|
var Base = require_base();
|
|
90924
95032
|
var observe = require_events();
|
|
90925
|
-
var { Subject } =
|
|
95033
|
+
var { Subject } = require_cjs5();
|
|
90926
95034
|
var EditorPrompt = class extends Base {
|
|
90927
95035
|
/**
|
|
90928
95036
|
* Start the Inquiry session
|
|
@@ -91093,6 +95201,8 @@ ${HOOK_MARKER}
|
|
|
91093
95201
|
# Checks API spec changes before pushing.
|
|
91094
95202
|
# The pre-push hook receives lines on stdin:
|
|
91095
95203
|
# <local ref> <local sha> <remote ref> <remote sha>
|
|
95204
|
+
#
|
|
95205
|
+
# Re-install after CLI upgrades: coderifts hook install
|
|
91096
95206
|
|
|
91097
95207
|
CODERIFTS_API_KEY=$(git config coderifts.apiKey)
|
|
91098
95208
|
SPEC_PATH=$(git config coderifts.specPath || echo "api/openapi.yaml")
|
|
@@ -91103,6 +95213,53 @@ if [ -z "$CODERIFTS_API_KEY" ]; then
|
|
|
91103
95213
|
exit 0 # Don't block if not configured
|
|
91104
95214
|
fi
|
|
91105
95215
|
|
|
95216
|
+
# --- helpers: three-state git blob read (present | absent | error) ---
|
|
95217
|
+
# Sets: BLOB_KIND, BLOB_CONTENT, BLOB_ERR. Never maps unreadable \u2192 empty string.
|
|
95218
|
+
git_blob_at() {
|
|
95219
|
+
_ref="$1"
|
|
95220
|
+
_path="$2"
|
|
95221
|
+
BLOB_CONTENT=""
|
|
95222
|
+
BLOB_ERR=""
|
|
95223
|
+
BLOB_KIND=""
|
|
95224
|
+
if ! git rev-parse --verify "$_ref^{commit}" >/dev/null 2>&1; then
|
|
95225
|
+
BLOB_KIND=error
|
|
95226
|
+
BLOB_ERR="GIT_ERROR: cannot resolve ref $_ref"
|
|
95227
|
+
return 1
|
|
95228
|
+
fi
|
|
95229
|
+
_errf=$(mktemp 2>/dev/null || echo "/tmp/coderifts-hook-err.$$")
|
|
95230
|
+
if BLOB_CONTENT=$(git show "$_ref:$_path" 2>"$_errf"); then
|
|
95231
|
+
BLOB_KIND=present
|
|
95232
|
+
rm -f "$_errf"
|
|
95233
|
+
return 0
|
|
95234
|
+
fi
|
|
95235
|
+
_err=$(cat "$_errf" 2>/dev/null)
|
|
95236
|
+
rm -f "$_errf"
|
|
95237
|
+
case "$_err" in
|
|
95238
|
+
*"does not exist in"*|*"exists on disk, but not in"*)
|
|
95239
|
+
BLOB_KIND=absent
|
|
95240
|
+
BLOB_CONTENT=""
|
|
95241
|
+
return 0
|
|
95242
|
+
;;
|
|
95243
|
+
esac
|
|
95244
|
+
BLOB_KIND=error
|
|
95245
|
+
BLOB_ERR="GIT_ERROR: git show $_ref:$_path failed"
|
|
95246
|
+
return 1
|
|
95247
|
+
}
|
|
95248
|
+
|
|
95249
|
+
# New-branch baseline: merge-base with default branch (not empty before).
|
|
95250
|
+
# Prints merge-base SHA on success; nonzero if none can be resolved.
|
|
95251
|
+
resolve_new_branch_base_ref() {
|
|
95252
|
+
_local="$1"
|
|
95253
|
+
for _cand in origin/HEAD origin/main origin/master main master; do
|
|
95254
|
+
_mb=$(git merge-base "$_local" "$_cand" 2>/dev/null) || continue
|
|
95255
|
+
if [ -n "$_mb" ] && [ "$_mb" != "$ZERO" ]; then
|
|
95256
|
+
echo "$_mb"
|
|
95257
|
+
return 0
|
|
95258
|
+
fi
|
|
95259
|
+
done
|
|
95260
|
+
return 1
|
|
95261
|
+
}
|
|
95262
|
+
|
|
91106
95263
|
# Read stdin lines provided by git pre-push
|
|
91107
95264
|
while read LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA; do
|
|
91108
95265
|
# Skip delete pushes
|
|
@@ -91110,41 +95267,93 @@ while read LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA; do
|
|
|
91110
95267
|
continue
|
|
91111
95268
|
fi
|
|
91112
95269
|
|
|
91113
|
-
#
|
|
91114
|
-
|
|
91115
|
-
|
|
95270
|
+
# after = local (about-to-be-pushed) commit \u2014 three-state
|
|
95271
|
+
if ! git_blob_at "$LOCAL_SHA" "$SPEC_PATH"; then
|
|
95272
|
+
echo "CodeRifts: $BLOB_ERR (after=$SPEC_PATH at $LOCAL_SHA). Fail-closed."
|
|
95273
|
+
exit 1
|
|
95274
|
+
fi
|
|
95275
|
+
if [ "$BLOB_KIND" = "absent" ]; then
|
|
91116
95276
|
continue # Spec doesn't exist in local commit, skip
|
|
91117
95277
|
fi
|
|
95278
|
+
HEAD_SPEC=$BLOB_CONTENT
|
|
91118
95279
|
|
|
91119
|
-
#
|
|
95280
|
+
# before = remote tip, or for new branch (zero remote SHA) a merge-base baseline
|
|
91120
95281
|
if [ "$REMOTE_SHA" = "$ZERO" ]; then
|
|
91121
|
-
|
|
91122
|
-
|
|
95282
|
+
BASE_REF=$(resolve_new_branch_base_ref "$LOCAL_SHA") || {
|
|
95283
|
+
echo "CodeRifts: GIT_ERROR \u2014 cannot resolve merge-base baseline for new branch (tried origin/HEAD, origin/main, origin/master, main, master). Fail-closed."
|
|
95284
|
+
exit 1
|
|
95285
|
+
}
|
|
91123
95286
|
else
|
|
91124
|
-
|
|
95287
|
+
BASE_REF=$REMOTE_SHA
|
|
91125
95288
|
fi
|
|
91126
95289
|
|
|
91127
|
-
|
|
91128
|
-
|
|
91129
|
-
|
|
95290
|
+
if ! git_blob_at "$BASE_REF" "$SPEC_PATH"; then
|
|
95291
|
+
echo "CodeRifts: $BLOB_ERR (before=$SPEC_PATH at $BASE_REF). Fail-closed \u2014 not treating as new spec."
|
|
95292
|
+
exit 1
|
|
95293
|
+
fi
|
|
95294
|
+
if [ "$BLOB_KIND" = "absent" ]; then
|
|
95295
|
+
# Honest NEW_ARTIFACT: path genuinely not at baseline
|
|
95296
|
+
echo "CodeRifts: New artifact (spec absent at baseline $BASE_REF:$SPEC_PATH); allowing push."
|
|
91130
95297
|
continue
|
|
91131
95298
|
fi
|
|
95299
|
+
BASE_SPEC=$BLOB_CONTENT
|
|
91132
95300
|
|
|
91133
95301
|
# If specs are identical, nothing to check
|
|
91134
95302
|
if [ "$BASE_SPEC" = "$HEAD_SPEC" ]; then
|
|
91135
95303
|
continue
|
|
91136
95304
|
fi
|
|
91137
95305
|
|
|
91138
|
-
echo "CodeRifts: Checking API spec changes..."
|
|
95306
|
+
echo "CodeRifts: Checking API spec changes (baseline $BASE_REF)..."
|
|
91139
95307
|
|
|
91140
95308
|
RESULT=$(curl -s -X POST https://app.coderifts.com/api/v1/diff \\
|
|
91141
95309
|
-H "Authorization: Bearer $CODERIFTS_API_KEY" \\
|
|
91142
95310
|
-H "Content-Type: application/json" \\
|
|
91143
95311
|
-d "{\\"before\\": $(echo "$BASE_SPEC" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))'), \\"after\\": $(echo "$HEAD_SPEC" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))')}")
|
|
91144
95312
|
|
|
91145
|
-
|
|
91146
|
-
|
|
91147
|
-
|
|
95313
|
+
# Prefer closed-set execution_action; omega_decision only when action is absent.
|
|
95314
|
+
# Severity (unchanged): BLOCK/STOP \u2192 exit 1; REQUIRE_APPROVAL/WARN \u2192 warn; unknown action \u2192 halt.
|
|
95315
|
+
DECISION=$(echo "$RESULT" | python3 -c '
|
|
95316
|
+
import sys, json
|
|
95317
|
+
try:
|
|
95318
|
+
d = json.load(sys.stdin)
|
|
95319
|
+
except Exception:
|
|
95320
|
+
print("ALLOW")
|
|
95321
|
+
raise SystemExit(0)
|
|
95322
|
+
ea = None
|
|
95323
|
+
dr = d.get("decision_result")
|
|
95324
|
+
if isinstance(dr, dict) and isinstance(dr.get("execution_action"), str):
|
|
95325
|
+
ea = dr["execution_action"]
|
|
95326
|
+
elif isinstance(d.get("execution_action"), str):
|
|
95327
|
+
ea = d["execution_action"]
|
|
95328
|
+
closed = {"CONTINUE", "CONTINUE_WITH_MONITORING", "REQUEST_APPROVAL", "STOP"}
|
|
95329
|
+
if ea is not None and ea != "":
|
|
95330
|
+
if ea not in closed:
|
|
95331
|
+
print("UNKNOWN")
|
|
95332
|
+
raise SystemExit(0)
|
|
95333
|
+
if ea in ("CONTINUE", "CONTINUE_WITH_MONITORING"):
|
|
95334
|
+
print("ALLOW")
|
|
95335
|
+
elif ea == "STOP":
|
|
95336
|
+
print("BLOCK")
|
|
95337
|
+
else:
|
|
95338
|
+
print("REQUIRE_APPROVAL")
|
|
95339
|
+
raise SystemExit(0)
|
|
95340
|
+
od = d.get("omega_decision") or d.get("decision") or "ALLOW"
|
|
95341
|
+
print(od)
|
|
95342
|
+
' 2>/dev/null)
|
|
95343
|
+
OMEGA=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('omega_api',0))" 2>/dev/null)
|
|
95344
|
+
BREAKING=$(echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('breaking_changes',[])))" 2>/dev/null)
|
|
95345
|
+
|
|
95346
|
+
if [ "$DECISION" = "UNKNOWN" ]; then
|
|
95347
|
+
echo ""
|
|
95348
|
+
echo "========================================"
|
|
95349
|
+
echo " CodeRifts: PUSH BLOCKED"
|
|
95350
|
+
echo "========================================"
|
|
95351
|
+
echo " Reason: unrecognised execution_action is not permission"
|
|
95352
|
+
echo " Fail-closed (unknown present action)."
|
|
95353
|
+
echo "========================================"
|
|
95354
|
+
echo ""
|
|
95355
|
+
exit 1
|
|
95356
|
+
fi
|
|
91148
95357
|
|
|
91149
95358
|
if [ "$DECISION" = "BLOCK" ]; then
|
|
91150
95359
|
echo ""
|
|
@@ -91212,6 +95421,10 @@ exit 0
|
|
|
91212
95421
|
console.log("");
|
|
91213
95422
|
console.log("Optionally set spec path (default: api/openapi.yaml):");
|
|
91214
95423
|
console.log(" git config coderifts.specPath path/to/openapi.yaml");
|
|
95424
|
+
console.log("");
|
|
95425
|
+
console.log("After upgrading the coderifts CLI, re-run this command so the installed");
|
|
95426
|
+
console.log("hook matches the package (already-installed hooks are not auto-updated):");
|
|
95427
|
+
console.log(" coderifts hook install");
|
|
91215
95428
|
}
|
|
91216
95429
|
function uninstall() {
|
|
91217
95430
|
const gitDir = findGitDir();
|
|
@@ -92581,6 +96794,7 @@ var require_mcp_poisoning_detector = __commonJS({
|
|
|
92581
96794
|
"../../src/mcp-poisoning-detector.js"(exports2, module2) {
|
|
92582
96795
|
"use strict";
|
|
92583
96796
|
var SENSITIVE_OBJECT = "(secrets?|credentials?|tokens?|passwords?|api[\\s_-]?keys?|private[\\s_-]?keys?|env|environment|conversation|chat\\s*history|context|user\\s*data|session)";
|
|
96797
|
+
var SENSITIVE_SCOPE = "(any|all|every|stored|user\\'?s?|the\\s+user\\'?s?|all\\s+environment)";
|
|
92584
96798
|
var SUSPICIOUS_PATTERNS = [
|
|
92585
96799
|
// Injection / "ignore your instructions" family. The trailing object
|
|
92586
96800
|
// (instructions|rules|prompts|context) is OPTIONAL so "ignore previous and ..."
|
|
@@ -92593,6 +96807,21 @@ var require_mcp_poisoning_detector = __commonJS({
|
|
|
92593
96807
|
/exfiltrate|steal|leak|send\s+to\s+external/i,
|
|
92594
96808
|
// Exfiltration-intent family: an action verb targeting a sensitive payload.
|
|
92595
96809
|
/\b(send|forward|copy|upload|post|transmit|exfiltrate|leak)\b[\s\S]{0,40}?\b(conversation|chat|history|context|messages?|credentials?|secrets?|tokens?|api\s*keys?|keys?|passwords?|data)\b/i,
|
|
96810
|
+
// Return/echo scoped sensitive material without a path ("return any stored credentials").
|
|
96811
|
+
// Scope word required — bare "return the new API token" must stay quiet.
|
|
96812
|
+
new RegExp(
|
|
96813
|
+
"\\b(return|echo|reveal|expose|send)\\b[\\s\\S]{0,30}?\\b" + SENSITIVE_SCOPE + "\\s+(secrets?|credentials?|tokens?|passwords?|private[\\s_-]?keys?|environment\\s+variables?|env)\\b",
|
|
96814
|
+
"i"
|
|
96815
|
+
),
|
|
96816
|
+
// Retrieve private-key material + echo/return (intent without a filesystem path).
|
|
96817
|
+
// Narrow: requires both a retrieve-class verb and an echo/return/reveal verb around key material.
|
|
96818
|
+
/\b(retrieve|fetch|extract|obtain|collect)\b[\s\S]{0,60}?\b(private[\s_-]?keys?(?:\s+material)?|secret[\s_-]?keys?|key\s+material)\b[\s\S]{0,50}?\b(echo|return|send|reveal|expose)\b/i,
|
|
96819
|
+
// Outbound destination without a named secret: exfil-shaped phrasing + http(s) URL.
|
|
96820
|
+
// Bare URL alone stays quiet (legit tools reference docs / configured webhook URLs).
|
|
96821
|
+
// "Sends the result to https://hooks…" (tool purpose) must NOT fire — requires "a copy"
|
|
96822
|
+
// or "also send" as the exfil marker, not mere "send … to <url>".
|
|
96823
|
+
/\b(send|forward|post|upload|transmit)\s+a\s+copy\b[\s\S]{0,50}?https?:\/\//i,
|
|
96824
|
+
/\balso\s+send\b[\s\S]{0,60}?https?:\/\//i,
|
|
92596
96825
|
/execute\s+(shell|command|code|system)/i,
|
|
92597
96826
|
/bypass\s+(auth|security|validation|filter)/i,
|
|
92598
96827
|
/override\s+(safety|policy|rules?)/i,
|
|
@@ -92604,8 +96833,8 @@ var require_mcp_poisoning_detector = __commonJS({
|
|
|
92604
96833
|
/return\s+secret|exfiltrat|leak\s+data/i
|
|
92605
96834
|
];
|
|
92606
96835
|
var URL_PATTERN = /https?:\/\/[^\s)'"]+/i;
|
|
92607
|
-
var SENSITIVE_PATH_PATTERN = /(~\/\.ssh|~\/\.cursor|~\/\.aws|\.aws\/|\.env\b|\/etc\/|mcp\.json|credentials|
|
|
92608
|
-
var CONTENT_MOVE_VERB_PATTERN = /\b(pass|send|return|forward|include|read|upload|post|transmit|copy|exfiltrate|leak)\b/i;
|
|
96836
|
+
var SENSITIVE_PATH_PATTERN = /(~\/\.ssh|~\/\.cursor|~\/\.aws|\.aws\/|\.env\b|\/etc\/|mcp\.json|id_rsa|\.ssh\/|\/credentials(?:\.|\/)|credentials\.(?:json|txt|pem|env)|\.credentials\b)/i;
|
|
96837
|
+
var CONTENT_MOVE_VERB_PATTERN = /\b(pass|send|return|forward|include|read|upload|post|transmit|copy|exfiltrate|leak|echo|reveal|expose)\b/i;
|
|
92609
96838
|
var BASE64_BLOB_PATTERN = /[A-Za-z0-9+/]{40,}={0,2}/;
|
|
92610
96839
|
function isLikelyBase64(s) {
|
|
92611
96840
|
if (/=$/.test(s)) return true;
|
|
@@ -93140,6 +97369,17 @@ program.command("diff <old-spec> <new-spec>").description("Compare two OpenAPI s
|
|
|
93140
97369
|
const { diff } = require_diff();
|
|
93141
97370
|
await diff(oldSpec, newSpec, options);
|
|
93142
97371
|
});
|
|
97372
|
+
program.command("deploy-gate").description("Gate a deploy on the current { environment, artifact } using a preflight receipt (phase-1 advisory)").option("--env <environment>", "Target environment (e.g. production, staging)").option("--artifact <artifact_id>", "Immutable artifact identity being deployed (content digest or commit SHA)").option("--receipt <file>", "Path to the deploy-scoped receipt JSON produced by preflight").option("--json", "Output the binding result as JSON").option("--enforce", "Treat the step as enforcing: attest ENFORCING and exit non-zero on a gate failure").action(async (options) => {
|
|
97373
|
+
const { runDeployGate } = require_deploy_gate2();
|
|
97374
|
+
await runDeployGate(options);
|
|
97375
|
+
});
|
|
97376
|
+
program.command("publish-gate").description("Gate npm publish on contract-artifact preflight (before=git baseline, after=working tree)").option("--spec <path>", "Contract artifact path (default: git config coderifts.specPath or api/openapi.yaml)").option("--json", "Machine-readable JSON result").action(async (options) => {
|
|
97377
|
+
const { runPublishGate } = require_publish_gate();
|
|
97378
|
+
const result = await runPublishGate(options);
|
|
97379
|
+
const code = result && typeof result.exitCode === "number" ? result.exitCode : 1;
|
|
97380
|
+
process.exitCode = code;
|
|
97381
|
+
process.exit(code);
|
|
97382
|
+
});
|
|
93143
97383
|
program.command("init [template]").description("Generate a .coderifts.yml from a policy template (startup, growth, fintech, public-api, microservices)").action(async (template) => {
|
|
93144
97384
|
const { init } = require_init();
|
|
93145
97385
|
await init(template);
|
|
@@ -93166,7 +97406,11 @@ corpusCmd.command("verify", { isDefault: true }).description("Evaluate every tru
|
|
|
93166
97406
|
const { corpusVerify } = require_corpus();
|
|
93167
97407
|
corpusVerify(options);
|
|
93168
97408
|
});
|
|
93169
|
-
program.
|
|
97409
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
97410
|
+
console.error(err);
|
|
97411
|
+
process.exitCode = typeof process.exitCode === "number" && process.exitCode !== 0 ? process.exitCode : 1;
|
|
97412
|
+
process.exit(process.exitCode);
|
|
97413
|
+
});
|
|
93170
97414
|
/*! Bundled license information:
|
|
93171
97415
|
|
|
93172
97416
|
safe-buffer/index.js:
|