agent-contracts 0.20.0 → 0.22.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 +47 -10
- package/cli-contract.yaml +76 -109
- package/dist/cli.js +2034 -1455
- package/dist/cli.js.map +1 -1
- package/dist/index.js +290 -9
- package/dist/index.js.map +1 -1
- package/docs/cli-reference.md +25 -107
- package/package.json +5 -4
package/dist/cli.js
CHANGED
|
@@ -7367,7 +7367,7 @@ var init_dist = __esm({
|
|
|
7367
7367
|
var require_stable = __commonJS({
|
|
7368
7368
|
"node_modules/safe-stable-stringify/stable.js"(exports, module) {
|
|
7369
7369
|
"use strict";
|
|
7370
|
-
module.exports =
|
|
7370
|
+
module.exports = stringify4;
|
|
7371
7371
|
var indentation = "";
|
|
7372
7372
|
var strEscapeSequencesRegExp = /[\x00-\x1f\x22\x5c]/;
|
|
7373
7373
|
var strEscapeSequencesReplacer = /[\x00-\x1f\x22\x5c]/g;
|
|
@@ -7943,7 +7943,7 @@ ${originalIndentation}`;
|
|
|
7943
7943
|
}
|
|
7944
7944
|
return arr;
|
|
7945
7945
|
}
|
|
7946
|
-
function
|
|
7946
|
+
function stringify4(value, replacer, spacer) {
|
|
7947
7947
|
var i3;
|
|
7948
7948
|
var indent = "";
|
|
7949
7949
|
indentation = "";
|
|
@@ -7982,9 +7982,9 @@ ${originalIndentation}`;
|
|
|
7982
7982
|
var require_safe_stable_stringify = __commonJS({
|
|
7983
7983
|
"node_modules/safe-stable-stringify/index.js"(exports, module) {
|
|
7984
7984
|
"use strict";
|
|
7985
|
-
var
|
|
7986
|
-
module.exports =
|
|
7987
|
-
|
|
7985
|
+
var stringify4 = require_stable();
|
|
7986
|
+
module.exports = stringify4;
|
|
7987
|
+
stringify4.default = stringify4;
|
|
7988
7988
|
}
|
|
7989
7989
|
});
|
|
7990
7990
|
|
|
@@ -34148,7 +34148,7 @@ var require_astring = __commonJS({
|
|
|
34148
34148
|
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
34149
34149
|
return Constructor;
|
|
34150
34150
|
}
|
|
34151
|
-
var
|
|
34151
|
+
var stringify4 = JSON.stringify;
|
|
34152
34152
|
if (!String.prototype.repeat) {
|
|
34153
34153
|
throw new Error("String.prototype.repeat is undefined, see https://github.com/davidbonnet/astring#installation");
|
|
34154
34154
|
}
|
|
@@ -35070,7 +35070,7 @@ var require_astring = __commonJS({
|
|
|
35070
35070
|
} else if (node.bigint != null) {
|
|
35071
35071
|
state.write(node.bigint + "n", node);
|
|
35072
35072
|
} else {
|
|
35073
|
-
state.write(
|
|
35073
|
+
state.write(stringify4(node.value), node);
|
|
35074
35074
|
}
|
|
35075
35075
|
},
|
|
35076
35076
|
RegExpLiteral: function RegExpLiteral(node, state) {
|
|
@@ -40457,9 +40457,9 @@ var require_errors = __commonJS({
|
|
|
40457
40457
|
}
|
|
40458
40458
|
});
|
|
40459
40459
|
|
|
40460
|
-
// node_modules/ajv-formats/dist/formats.js
|
|
40460
|
+
// node_modules/@stoplight/spectral-core/node_modules/ajv-formats/dist/formats.js
|
|
40461
40461
|
var require_formats2 = __commonJS({
|
|
40462
|
-
"node_modules/ajv-formats/dist/formats.js"(exports) {
|
|
40462
|
+
"node_modules/@stoplight/spectral-core/node_modules/ajv-formats/dist/formats.js"(exports) {
|
|
40463
40463
|
"use strict";
|
|
40464
40464
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40465
40465
|
exports.formatNames = exports.fastFormats = exports.fullFormats = void 0;
|
|
@@ -40624,9 +40624,9 @@ var require_formats2 = __commonJS({
|
|
|
40624
40624
|
}
|
|
40625
40625
|
});
|
|
40626
40626
|
|
|
40627
|
-
// node_modules/ajv-formats/dist/limit.js
|
|
40627
|
+
// node_modules/@stoplight/spectral-core/node_modules/ajv-formats/dist/limit.js
|
|
40628
40628
|
var require_limit = __commonJS({
|
|
40629
|
-
"node_modules/ajv-formats/dist/limit.js"(exports) {
|
|
40629
|
+
"node_modules/@stoplight/spectral-core/node_modules/ajv-formats/dist/limit.js"(exports) {
|
|
40630
40630
|
"use strict";
|
|
40631
40631
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40632
40632
|
exports.formatLimitDefinition = void 0;
|
|
@@ -40696,9 +40696,9 @@ var require_limit = __commonJS({
|
|
|
40696
40696
|
}
|
|
40697
40697
|
});
|
|
40698
40698
|
|
|
40699
|
-
// node_modules/ajv-formats/dist/index.js
|
|
40699
|
+
// node_modules/@stoplight/spectral-core/node_modules/ajv-formats/dist/index.js
|
|
40700
40700
|
var require_dist7 = __commonJS({
|
|
40701
|
-
"node_modules/ajv-formats/dist/index.js"(exports, module) {
|
|
40701
|
+
"node_modules/@stoplight/spectral-core/node_modules/ajv-formats/dist/index.js"(exports, module) {
|
|
40702
40702
|
"use strict";
|
|
40703
40703
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40704
40704
|
var formats_1 = require_formats2();
|
|
@@ -48101,6 +48101,287 @@ var require_dist12 = __commonJS({
|
|
|
48101
48101
|
}
|
|
48102
48102
|
});
|
|
48103
48103
|
|
|
48104
|
+
// node_modules/@stoplight/spectral-functions/node_modules/ajv-formats/dist/formats.js
|
|
48105
|
+
var require_formats3 = __commonJS({
|
|
48106
|
+
"node_modules/@stoplight/spectral-functions/node_modules/ajv-formats/dist/formats.js"(exports) {
|
|
48107
|
+
"use strict";
|
|
48108
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48109
|
+
exports.formatNames = exports.fastFormats = exports.fullFormats = void 0;
|
|
48110
|
+
function fmtDef(validate, compare) {
|
|
48111
|
+
return { validate, compare };
|
|
48112
|
+
}
|
|
48113
|
+
exports.fullFormats = {
|
|
48114
|
+
// date: http://tools.ietf.org/html/rfc3339#section-5.6
|
|
48115
|
+
date: fmtDef(date, compareDate),
|
|
48116
|
+
// date-time: http://tools.ietf.org/html/rfc3339#section-5.6
|
|
48117
|
+
time: fmtDef(time, compareTime),
|
|
48118
|
+
"date-time": fmtDef(date_time, compareDateTime),
|
|
48119
|
+
// duration: https://tools.ietf.org/html/rfc3339#appendix-A
|
|
48120
|
+
duration: /^P(?!$)((\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?|(\d+W)?)$/,
|
|
48121
|
+
uri,
|
|
48122
|
+
"uri-reference": /^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i,
|
|
48123
|
+
// uri-template: https://tools.ietf.org/html/rfc6570
|
|
48124
|
+
"uri-template": /^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,
|
|
48125
|
+
// For the source: https://gist.github.com/dperini/729294
|
|
48126
|
+
// For test cases: https://mathiasbynens.be/demo/url-regex
|
|
48127
|
+
url: /^(?:https?|ftp):\/\/(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)(?:\.(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu,
|
|
48128
|
+
email: /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i,
|
|
48129
|
+
hostname: /^(?=.{1,253}\.?$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*\.?$/i,
|
|
48130
|
+
// optimized https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html
|
|
48131
|
+
ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,
|
|
48132
|
+
ipv6: /^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i,
|
|
48133
|
+
regex,
|
|
48134
|
+
// uuid: http://tools.ietf.org/html/rfc4122
|
|
48135
|
+
uuid: /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,
|
|
48136
|
+
// JSON-pointer: https://tools.ietf.org/html/rfc6901
|
|
48137
|
+
// uri fragment: https://tools.ietf.org/html/rfc3986#appendix-A
|
|
48138
|
+
"json-pointer": /^(?:\/(?:[^~/]|~0|~1)*)*$/,
|
|
48139
|
+
"json-pointer-uri-fragment": /^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,
|
|
48140
|
+
// relative JSON-pointer: http://tools.ietf.org/html/draft-luff-relative-json-pointer-00
|
|
48141
|
+
"relative-json-pointer": /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/,
|
|
48142
|
+
// the following formats are used by the openapi specification: https://spec.openapis.org/oas/v3.0.0#data-types
|
|
48143
|
+
// byte: https://github.com/miguelmota/is-base64
|
|
48144
|
+
byte,
|
|
48145
|
+
// signed 32 bit integer
|
|
48146
|
+
int32: { type: "number", validate: validateInt32 },
|
|
48147
|
+
// signed 64 bit integer
|
|
48148
|
+
int64: { type: "number", validate: validateInt64 },
|
|
48149
|
+
// C-type float
|
|
48150
|
+
float: { type: "number", validate: validateNumber },
|
|
48151
|
+
// C-type double
|
|
48152
|
+
double: { type: "number", validate: validateNumber },
|
|
48153
|
+
// hint to the UI to hide input strings
|
|
48154
|
+
password: true,
|
|
48155
|
+
// unchecked string payload
|
|
48156
|
+
binary: true
|
|
48157
|
+
};
|
|
48158
|
+
exports.fastFormats = {
|
|
48159
|
+
...exports.fullFormats,
|
|
48160
|
+
date: fmtDef(/^\d\d\d\d-[0-1]\d-[0-3]\d$/, compareDate),
|
|
48161
|
+
time: fmtDef(/^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)?$/i, compareTime),
|
|
48162
|
+
"date-time": fmtDef(/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i, compareDateTime),
|
|
48163
|
+
// uri: https://github.com/mafintosh/is-my-json-valid/blob/master/formats.js
|
|
48164
|
+
uri: /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/)?[^\s]*$/i,
|
|
48165
|
+
"uri-reference": /^(?:(?:[a-z][a-z0-9+\-.]*:)?\/?\/)?(?:[^\\\s#][^\s#]*)?(?:#[^\\\s]*)?$/i,
|
|
48166
|
+
// email (sources from jsen validator):
|
|
48167
|
+
// http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address#answer-8829363
|
|
48168
|
+
// http://www.w3.org/TR/html5/forms.html#valid-e-mail-address (search for 'wilful violation')
|
|
48169
|
+
email: /^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i
|
|
48170
|
+
};
|
|
48171
|
+
exports.formatNames = Object.keys(exports.fullFormats);
|
|
48172
|
+
function isLeapYear(year) {
|
|
48173
|
+
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
48174
|
+
}
|
|
48175
|
+
var DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
|
|
48176
|
+
var DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
48177
|
+
function date(str) {
|
|
48178
|
+
const matches = DATE.exec(str);
|
|
48179
|
+
if (!matches)
|
|
48180
|
+
return false;
|
|
48181
|
+
const year = +matches[1];
|
|
48182
|
+
const month = +matches[2];
|
|
48183
|
+
const day = +matches[3];
|
|
48184
|
+
return month >= 1 && month <= 12 && day >= 1 && day <= (month === 2 && isLeapYear(year) ? 29 : DAYS[month]);
|
|
48185
|
+
}
|
|
48186
|
+
function compareDate(d1, d2) {
|
|
48187
|
+
if (!(d1 && d2))
|
|
48188
|
+
return void 0;
|
|
48189
|
+
if (d1 > d2)
|
|
48190
|
+
return 1;
|
|
48191
|
+
if (d1 < d2)
|
|
48192
|
+
return -1;
|
|
48193
|
+
return 0;
|
|
48194
|
+
}
|
|
48195
|
+
var TIME = /^(\d\d):(\d\d):(\d\d)(\.\d+)?(z|[+-]\d\d(?::?\d\d)?)?$/i;
|
|
48196
|
+
function time(str, withTimeZone) {
|
|
48197
|
+
const matches = TIME.exec(str);
|
|
48198
|
+
if (!matches)
|
|
48199
|
+
return false;
|
|
48200
|
+
const hour = +matches[1];
|
|
48201
|
+
const minute = +matches[2];
|
|
48202
|
+
const second = +matches[3];
|
|
48203
|
+
const timeZone = matches[5];
|
|
48204
|
+
return (hour <= 23 && minute <= 59 && second <= 59 || hour === 23 && minute === 59 && second === 60) && (!withTimeZone || timeZone !== "");
|
|
48205
|
+
}
|
|
48206
|
+
function compareTime(t1, t22) {
|
|
48207
|
+
if (!(t1 && t22))
|
|
48208
|
+
return void 0;
|
|
48209
|
+
const a1 = TIME.exec(t1);
|
|
48210
|
+
const a22 = TIME.exec(t22);
|
|
48211
|
+
if (!(a1 && a22))
|
|
48212
|
+
return void 0;
|
|
48213
|
+
t1 = a1[1] + a1[2] + a1[3] + (a1[4] || "");
|
|
48214
|
+
t22 = a22[1] + a22[2] + a22[3] + (a22[4] || "");
|
|
48215
|
+
if (t1 > t22)
|
|
48216
|
+
return 1;
|
|
48217
|
+
if (t1 < t22)
|
|
48218
|
+
return -1;
|
|
48219
|
+
return 0;
|
|
48220
|
+
}
|
|
48221
|
+
var DATE_TIME_SEPARATOR = /t|\s/i;
|
|
48222
|
+
function date_time(str) {
|
|
48223
|
+
const dateTime = str.split(DATE_TIME_SEPARATOR);
|
|
48224
|
+
return dateTime.length === 2 && date(dateTime[0]) && time(dateTime[1], true);
|
|
48225
|
+
}
|
|
48226
|
+
function compareDateTime(dt1, dt2) {
|
|
48227
|
+
if (!(dt1 && dt2))
|
|
48228
|
+
return void 0;
|
|
48229
|
+
const [d1, t1] = dt1.split(DATE_TIME_SEPARATOR);
|
|
48230
|
+
const [d2, t22] = dt2.split(DATE_TIME_SEPARATOR);
|
|
48231
|
+
const res = compareDate(d1, d2);
|
|
48232
|
+
if (res === void 0)
|
|
48233
|
+
return void 0;
|
|
48234
|
+
return res || compareTime(t1, t22);
|
|
48235
|
+
}
|
|
48236
|
+
var NOT_URI_FRAGMENT = /\/|:/;
|
|
48237
|
+
var URI = /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
|
|
48238
|
+
function uri(str) {
|
|
48239
|
+
return NOT_URI_FRAGMENT.test(str) && URI.test(str);
|
|
48240
|
+
}
|
|
48241
|
+
var BYTE = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gm;
|
|
48242
|
+
function byte(str) {
|
|
48243
|
+
BYTE.lastIndex = 0;
|
|
48244
|
+
return BYTE.test(str);
|
|
48245
|
+
}
|
|
48246
|
+
var MIN_INT32 = -(2 ** 31);
|
|
48247
|
+
var MAX_INT32 = 2 ** 31 - 1;
|
|
48248
|
+
function validateInt32(value) {
|
|
48249
|
+
return Number.isInteger(value) && value <= MAX_INT32 && value >= MIN_INT32;
|
|
48250
|
+
}
|
|
48251
|
+
function validateInt64(value) {
|
|
48252
|
+
return Number.isInteger(value);
|
|
48253
|
+
}
|
|
48254
|
+
function validateNumber() {
|
|
48255
|
+
return true;
|
|
48256
|
+
}
|
|
48257
|
+
var Z_ANCHOR = /[^\\]\\Z/;
|
|
48258
|
+
function regex(str) {
|
|
48259
|
+
if (Z_ANCHOR.test(str))
|
|
48260
|
+
return false;
|
|
48261
|
+
try {
|
|
48262
|
+
new RegExp(str);
|
|
48263
|
+
return true;
|
|
48264
|
+
} catch (e3) {
|
|
48265
|
+
return false;
|
|
48266
|
+
}
|
|
48267
|
+
}
|
|
48268
|
+
}
|
|
48269
|
+
});
|
|
48270
|
+
|
|
48271
|
+
// node_modules/@stoplight/spectral-functions/node_modules/ajv-formats/dist/limit.js
|
|
48272
|
+
var require_limit2 = __commonJS({
|
|
48273
|
+
"node_modules/@stoplight/spectral-functions/node_modules/ajv-formats/dist/limit.js"(exports) {
|
|
48274
|
+
"use strict";
|
|
48275
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48276
|
+
exports.formatLimitDefinition = void 0;
|
|
48277
|
+
var ajv_1 = __require("ajv");
|
|
48278
|
+
var codegen_1 = __require("ajv/dist/compile/codegen");
|
|
48279
|
+
var ops = codegen_1.operators;
|
|
48280
|
+
var KWDs = {
|
|
48281
|
+
formatMaximum: { okStr: "<=", ok: ops.LTE, fail: ops.GT },
|
|
48282
|
+
formatMinimum: { okStr: ">=", ok: ops.GTE, fail: ops.LT },
|
|
48283
|
+
formatExclusiveMaximum: { okStr: "<", ok: ops.LT, fail: ops.GTE },
|
|
48284
|
+
formatExclusiveMinimum: { okStr: ">", ok: ops.GT, fail: ops.LTE }
|
|
48285
|
+
};
|
|
48286
|
+
var error = {
|
|
48287
|
+
message: ({ keyword, schemaCode }) => codegen_1.str`should be ${KWDs[keyword].okStr} ${schemaCode}`,
|
|
48288
|
+
params: ({ keyword, schemaCode }) => codegen_1._`{comparison: ${KWDs[keyword].okStr}, limit: ${schemaCode}}`
|
|
48289
|
+
};
|
|
48290
|
+
exports.formatLimitDefinition = {
|
|
48291
|
+
keyword: Object.keys(KWDs),
|
|
48292
|
+
type: "string",
|
|
48293
|
+
schemaType: "string",
|
|
48294
|
+
$data: true,
|
|
48295
|
+
error,
|
|
48296
|
+
code(cxt) {
|
|
48297
|
+
const { gen, data, schemaCode, keyword, it } = cxt;
|
|
48298
|
+
const { opts, self: self2 } = it;
|
|
48299
|
+
if (!opts.validateFormats)
|
|
48300
|
+
return;
|
|
48301
|
+
const fCxt = new ajv_1.KeywordCxt(it, self2.RULES.all.format.definition, "format");
|
|
48302
|
+
if (fCxt.$data)
|
|
48303
|
+
validate$DataFormat();
|
|
48304
|
+
else
|
|
48305
|
+
validateFormat();
|
|
48306
|
+
function validate$DataFormat() {
|
|
48307
|
+
const fmts = gen.scopeValue("formats", {
|
|
48308
|
+
ref: self2.formats,
|
|
48309
|
+
code: opts.code.formats
|
|
48310
|
+
});
|
|
48311
|
+
const fmt = gen.const("fmt", codegen_1._`${fmts}[${fCxt.schemaCode}]`);
|
|
48312
|
+
cxt.fail$data(codegen_1.or(codegen_1._`typeof ${fmt} != "object"`, codegen_1._`${fmt} instanceof RegExp`, codegen_1._`typeof ${fmt}.compare != "function"`, compareCode(fmt)));
|
|
48313
|
+
}
|
|
48314
|
+
function validateFormat() {
|
|
48315
|
+
const format2 = fCxt.schema;
|
|
48316
|
+
const fmtDef = self2.formats[format2];
|
|
48317
|
+
if (!fmtDef || fmtDef === true)
|
|
48318
|
+
return;
|
|
48319
|
+
if (typeof fmtDef != "object" || fmtDef instanceof RegExp || typeof fmtDef.compare != "function") {
|
|
48320
|
+
throw new Error(`"${keyword}": format "${format2}" does not define "compare" function`);
|
|
48321
|
+
}
|
|
48322
|
+
const fmt = gen.scopeValue("formats", {
|
|
48323
|
+
key: format2,
|
|
48324
|
+
ref: fmtDef,
|
|
48325
|
+
code: opts.code.formats ? codegen_1._`${opts.code.formats}${codegen_1.getProperty(format2)}` : void 0
|
|
48326
|
+
});
|
|
48327
|
+
cxt.fail$data(compareCode(fmt));
|
|
48328
|
+
}
|
|
48329
|
+
function compareCode(fmt) {
|
|
48330
|
+
return codegen_1._`${fmt}.compare(${data}, ${schemaCode}) ${KWDs[keyword].fail} 0`;
|
|
48331
|
+
}
|
|
48332
|
+
},
|
|
48333
|
+
dependencies: ["format"]
|
|
48334
|
+
};
|
|
48335
|
+
var formatLimitPlugin = (ajv2) => {
|
|
48336
|
+
ajv2.addKeyword(exports.formatLimitDefinition);
|
|
48337
|
+
return ajv2;
|
|
48338
|
+
};
|
|
48339
|
+
exports.default = formatLimitPlugin;
|
|
48340
|
+
}
|
|
48341
|
+
});
|
|
48342
|
+
|
|
48343
|
+
// node_modules/@stoplight/spectral-functions/node_modules/ajv-formats/dist/index.js
|
|
48344
|
+
var require_dist13 = __commonJS({
|
|
48345
|
+
"node_modules/@stoplight/spectral-functions/node_modules/ajv-formats/dist/index.js"(exports, module) {
|
|
48346
|
+
"use strict";
|
|
48347
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48348
|
+
var formats_1 = require_formats3();
|
|
48349
|
+
var limit_1 = require_limit2();
|
|
48350
|
+
var codegen_1 = __require("ajv/dist/compile/codegen");
|
|
48351
|
+
var fullName = new codegen_1.Name("fullFormats");
|
|
48352
|
+
var fastName = new codegen_1.Name("fastFormats");
|
|
48353
|
+
var formatsPlugin = (ajv2, opts = { keywords: true }) => {
|
|
48354
|
+
if (Array.isArray(opts)) {
|
|
48355
|
+
addFormats(ajv2, opts, formats_1.fullFormats, fullName);
|
|
48356
|
+
return ajv2;
|
|
48357
|
+
}
|
|
48358
|
+
const [formats, exportName] = opts.mode === "fast" ? [formats_1.fastFormats, fastName] : [formats_1.fullFormats, fullName];
|
|
48359
|
+
const list = opts.formats || formats_1.formatNames;
|
|
48360
|
+
addFormats(ajv2, list, formats, exportName);
|
|
48361
|
+
if (opts.keywords)
|
|
48362
|
+
limit_1.default(ajv2);
|
|
48363
|
+
return ajv2;
|
|
48364
|
+
};
|
|
48365
|
+
formatsPlugin.get = (name, mode = "full") => {
|
|
48366
|
+
const formats = mode === "fast" ? formats_1.fastFormats : formats_1.fullFormats;
|
|
48367
|
+
const f2 = formats[name];
|
|
48368
|
+
if (!f2)
|
|
48369
|
+
throw new Error(`Unknown format "${name}"`);
|
|
48370
|
+
return f2;
|
|
48371
|
+
};
|
|
48372
|
+
function addFormats(ajv2, list, fs, exportName) {
|
|
48373
|
+
var _a;
|
|
48374
|
+
var _b;
|
|
48375
|
+
(_a = (_b = ajv2.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = codegen_1._`require("ajv-formats/dist/formats").${exportName}`;
|
|
48376
|
+
for (const f2 of list)
|
|
48377
|
+
ajv2.addFormat(f2, fs[f2]);
|
|
48378
|
+
}
|
|
48379
|
+
module.exports = exports = formatsPlugin;
|
|
48380
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48381
|
+
exports.default = formatsPlugin;
|
|
48382
|
+
}
|
|
48383
|
+
});
|
|
48384
|
+
|
|
48104
48385
|
// node_modules/@stoplight/spectral-functions/dist/schema/draft4.json
|
|
48105
48386
|
var require_draft42 = __commonJS({
|
|
48106
48387
|
"node_modules/@stoplight/spectral-functions/dist/schema/draft4.json"(exports, module) {
|
|
@@ -48255,7 +48536,7 @@ var require_ajv2 = __commonJS({
|
|
|
48255
48536
|
var _2019_1 = (0, tslib_1.__importDefault)(__require("ajv/dist/2019"));
|
|
48256
48537
|
var _2020_1 = (0, tslib_1.__importDefault)(__require("ajv/dist/2020"));
|
|
48257
48538
|
var ajv_draft_04_1 = (0, tslib_1.__importDefault)(require_dist12());
|
|
48258
|
-
var ajv_formats_1 = (0, tslib_1.__importDefault)(
|
|
48539
|
+
var ajv_formats_1 = (0, tslib_1.__importDefault)(require_dist13());
|
|
48259
48540
|
var ajv_errors_1 = (0, tslib_1.__importDefault)(require_dist8());
|
|
48260
48541
|
var draft6MetaSchema = (0, tslib_1.__importStar)(__require("ajv/dist/refs/json-schema-draft-06.json"));
|
|
48261
48542
|
var draft4MetaSchema = (0, tslib_1.__importStar)(require_draft42());
|
|
@@ -48546,7 +48827,7 @@ var require_or = __commonJS({
|
|
|
48546
48827
|
});
|
|
48547
48828
|
|
|
48548
48829
|
// node_modules/@stoplight/spectral-functions/dist/index.js
|
|
48549
|
-
var
|
|
48830
|
+
var require_dist14 = __commonJS({
|
|
48550
48831
|
"node_modules/@stoplight/spectral-functions/dist/index.js"(exports) {
|
|
48551
48832
|
"use strict";
|
|
48552
48833
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -48611,11 +48892,579 @@ var require_dist13 = __commonJS({
|
|
|
48611
48892
|
import { readFileSync as readFileSync2 } from "fs";
|
|
48612
48893
|
import { fileURLToPath } from "url";
|
|
48613
48894
|
import { resolve as resolve8, dirname as dirname8 } from "path";
|
|
48614
|
-
import { Command as Command9 } from "commander";
|
|
48615
48895
|
|
|
48616
|
-
// src/cli/
|
|
48896
|
+
// src/generated/cli-contract/program.ts
|
|
48617
48897
|
import { Command } from "commander";
|
|
48618
48898
|
|
|
48899
|
+
// src/generated/cli-contract/policy.ts
|
|
48900
|
+
import { derivePolicy, isOptionActive } from "cli-contracts/policy";
|
|
48901
|
+
var commandDefinitions = {
|
|
48902
|
+
"resolve": {
|
|
48903
|
+
"options": [
|
|
48904
|
+
{
|
|
48905
|
+
"name": "config",
|
|
48906
|
+
"schema": {
|
|
48907
|
+
"type": "string"
|
|
48908
|
+
},
|
|
48909
|
+
"file": {
|
|
48910
|
+
"mode": "read",
|
|
48911
|
+
"exists": false,
|
|
48912
|
+
"mediaType": "application/yaml",
|
|
48913
|
+
"encoding": "utf-8"
|
|
48914
|
+
}
|
|
48915
|
+
},
|
|
48916
|
+
{
|
|
48917
|
+
"name": "team",
|
|
48918
|
+
"schema": {
|
|
48919
|
+
"type": "string"
|
|
48920
|
+
}
|
|
48921
|
+
},
|
|
48922
|
+
{
|
|
48923
|
+
"name": "format",
|
|
48924
|
+
"schema": {
|
|
48925
|
+
"type": "string",
|
|
48926
|
+
"enum": [
|
|
48927
|
+
"text",
|
|
48928
|
+
"json"
|
|
48929
|
+
],
|
|
48930
|
+
"default": "text"
|
|
48931
|
+
}
|
|
48932
|
+
},
|
|
48933
|
+
{
|
|
48934
|
+
"name": "expand-defaults",
|
|
48935
|
+
"schema": {
|
|
48936
|
+
"type": "boolean",
|
|
48937
|
+
"default": false
|
|
48938
|
+
}
|
|
48939
|
+
}
|
|
48940
|
+
]
|
|
48941
|
+
},
|
|
48942
|
+
"validate": {
|
|
48943
|
+
"options": [
|
|
48944
|
+
{
|
|
48945
|
+
"name": "config",
|
|
48946
|
+
"schema": {
|
|
48947
|
+
"type": "string"
|
|
48948
|
+
},
|
|
48949
|
+
"file": {
|
|
48950
|
+
"mode": "read",
|
|
48951
|
+
"exists": false,
|
|
48952
|
+
"mediaType": "application/yaml",
|
|
48953
|
+
"encoding": "utf-8"
|
|
48954
|
+
}
|
|
48955
|
+
},
|
|
48956
|
+
{
|
|
48957
|
+
"name": "team",
|
|
48958
|
+
"schema": {
|
|
48959
|
+
"type": "string"
|
|
48960
|
+
}
|
|
48961
|
+
},
|
|
48962
|
+
{
|
|
48963
|
+
"name": "format",
|
|
48964
|
+
"schema": {
|
|
48965
|
+
"type": "string",
|
|
48966
|
+
"enum": [
|
|
48967
|
+
"text",
|
|
48968
|
+
"json"
|
|
48969
|
+
],
|
|
48970
|
+
"default": "text"
|
|
48971
|
+
}
|
|
48972
|
+
},
|
|
48973
|
+
{
|
|
48974
|
+
"name": "quiet",
|
|
48975
|
+
"schema": {
|
|
48976
|
+
"type": "boolean",
|
|
48977
|
+
"default": false
|
|
48978
|
+
}
|
|
48979
|
+
},
|
|
48980
|
+
{
|
|
48981
|
+
"name": "strict",
|
|
48982
|
+
"schema": {
|
|
48983
|
+
"type": "boolean",
|
|
48984
|
+
"default": false
|
|
48985
|
+
}
|
|
48986
|
+
}
|
|
48987
|
+
]
|
|
48988
|
+
},
|
|
48989
|
+
"lint": {
|
|
48990
|
+
"options": [
|
|
48991
|
+
{
|
|
48992
|
+
"name": "config",
|
|
48993
|
+
"schema": {
|
|
48994
|
+
"type": "string"
|
|
48995
|
+
},
|
|
48996
|
+
"file": {
|
|
48997
|
+
"mode": "read",
|
|
48998
|
+
"exists": false,
|
|
48999
|
+
"mediaType": "application/yaml",
|
|
49000
|
+
"encoding": "utf-8"
|
|
49001
|
+
}
|
|
49002
|
+
},
|
|
49003
|
+
{
|
|
49004
|
+
"name": "team",
|
|
49005
|
+
"schema": {
|
|
49006
|
+
"type": "string"
|
|
49007
|
+
}
|
|
49008
|
+
},
|
|
49009
|
+
{
|
|
49010
|
+
"name": "format",
|
|
49011
|
+
"schema": {
|
|
49012
|
+
"type": "string",
|
|
49013
|
+
"enum": [
|
|
49014
|
+
"text",
|
|
49015
|
+
"json"
|
|
49016
|
+
],
|
|
49017
|
+
"default": "text"
|
|
49018
|
+
}
|
|
49019
|
+
},
|
|
49020
|
+
{
|
|
49021
|
+
"name": "quiet",
|
|
49022
|
+
"schema": {
|
|
49023
|
+
"type": "boolean",
|
|
49024
|
+
"default": false
|
|
49025
|
+
}
|
|
49026
|
+
},
|
|
49027
|
+
{
|
|
49028
|
+
"name": "strict",
|
|
49029
|
+
"schema": {
|
|
49030
|
+
"type": "boolean",
|
|
49031
|
+
"default": false
|
|
49032
|
+
}
|
|
49033
|
+
}
|
|
49034
|
+
]
|
|
49035
|
+
},
|
|
49036
|
+
"render": {
|
|
49037
|
+
"effects": {
|
|
49038
|
+
"riskLevel": "medium",
|
|
49039
|
+
"writes": [
|
|
49040
|
+
{
|
|
49041
|
+
"target": "configured render output paths",
|
|
49042
|
+
"description": "rendered template files from DSL input",
|
|
49043
|
+
"overwrite": true,
|
|
49044
|
+
"idempotent": true,
|
|
49045
|
+
"idempotentNote": "Output is deterministic from DSL input and templates. Repeated runs produce identical files."
|
|
49046
|
+
}
|
|
49047
|
+
]
|
|
49048
|
+
},
|
|
49049
|
+
"options": [
|
|
49050
|
+
{
|
|
49051
|
+
"name": "config",
|
|
49052
|
+
"schema": {
|
|
49053
|
+
"type": "string"
|
|
49054
|
+
},
|
|
49055
|
+
"file": {
|
|
49056
|
+
"mode": "read",
|
|
49057
|
+
"exists": false,
|
|
49058
|
+
"mediaType": "application/yaml",
|
|
49059
|
+
"encoding": "utf-8"
|
|
49060
|
+
}
|
|
49061
|
+
},
|
|
49062
|
+
{
|
|
49063
|
+
"name": "team",
|
|
49064
|
+
"schema": {
|
|
49065
|
+
"type": "string"
|
|
49066
|
+
}
|
|
49067
|
+
},
|
|
49068
|
+
{
|
|
49069
|
+
"name": "check",
|
|
49070
|
+
"schema": {
|
|
49071
|
+
"type": "boolean",
|
|
49072
|
+
"default": false
|
|
49073
|
+
}
|
|
49074
|
+
},
|
|
49075
|
+
{
|
|
49076
|
+
"name": "quiet",
|
|
49077
|
+
"schema": {
|
|
49078
|
+
"type": "boolean",
|
|
49079
|
+
"default": false
|
|
49080
|
+
}
|
|
49081
|
+
}
|
|
49082
|
+
]
|
|
49083
|
+
},
|
|
49084
|
+
"check": {
|
|
49085
|
+
"options": [
|
|
49086
|
+
{
|
|
49087
|
+
"name": "config",
|
|
49088
|
+
"schema": {
|
|
49089
|
+
"type": "string"
|
|
49090
|
+
},
|
|
49091
|
+
"file": {
|
|
49092
|
+
"mode": "read",
|
|
49093
|
+
"exists": false,
|
|
49094
|
+
"mediaType": "application/yaml",
|
|
49095
|
+
"encoding": "utf-8"
|
|
49096
|
+
}
|
|
49097
|
+
},
|
|
49098
|
+
{
|
|
49099
|
+
"name": "team",
|
|
49100
|
+
"schema": {
|
|
49101
|
+
"type": "string"
|
|
49102
|
+
}
|
|
49103
|
+
},
|
|
49104
|
+
{
|
|
49105
|
+
"name": "format",
|
|
49106
|
+
"schema": {
|
|
49107
|
+
"type": "string",
|
|
49108
|
+
"enum": [
|
|
49109
|
+
"text",
|
|
49110
|
+
"json"
|
|
49111
|
+
],
|
|
49112
|
+
"default": "text"
|
|
49113
|
+
}
|
|
49114
|
+
},
|
|
49115
|
+
{
|
|
49116
|
+
"name": "quiet",
|
|
49117
|
+
"schema": {
|
|
49118
|
+
"type": "boolean",
|
|
49119
|
+
"default": false
|
|
49120
|
+
}
|
|
49121
|
+
},
|
|
49122
|
+
{
|
|
49123
|
+
"name": "strict",
|
|
49124
|
+
"schema": {
|
|
49125
|
+
"type": "boolean",
|
|
49126
|
+
"default": false
|
|
49127
|
+
}
|
|
49128
|
+
}
|
|
49129
|
+
]
|
|
49130
|
+
},
|
|
49131
|
+
"score": {
|
|
49132
|
+
"options": [
|
|
49133
|
+
{
|
|
49134
|
+
"name": "config",
|
|
49135
|
+
"schema": {
|
|
49136
|
+
"type": "string"
|
|
49137
|
+
},
|
|
49138
|
+
"file": {
|
|
49139
|
+
"mode": "read",
|
|
49140
|
+
"exists": false,
|
|
49141
|
+
"mediaType": "application/yaml",
|
|
49142
|
+
"encoding": "utf-8"
|
|
49143
|
+
}
|
|
49144
|
+
},
|
|
49145
|
+
{
|
|
49146
|
+
"name": "team",
|
|
49147
|
+
"schema": {
|
|
49148
|
+
"type": "string"
|
|
49149
|
+
}
|
|
49150
|
+
},
|
|
49151
|
+
{
|
|
49152
|
+
"name": "format",
|
|
49153
|
+
"schema": {
|
|
49154
|
+
"type": "string",
|
|
49155
|
+
"enum": [
|
|
49156
|
+
"text",
|
|
49157
|
+
"json"
|
|
49158
|
+
],
|
|
49159
|
+
"default": "text"
|
|
49160
|
+
}
|
|
49161
|
+
},
|
|
49162
|
+
{
|
|
49163
|
+
"name": "threshold",
|
|
49164
|
+
"schema": {
|
|
49165
|
+
"type": "integer"
|
|
49166
|
+
}
|
|
49167
|
+
}
|
|
49168
|
+
]
|
|
49169
|
+
},
|
|
49170
|
+
"audit": {
|
|
49171
|
+
"effects": {
|
|
49172
|
+
"riskLevel": "medium",
|
|
49173
|
+
"network": {
|
|
49174
|
+
"description": "LLM API calls to configured adapter (e.g. OpenAI, Gemini, Cursor). Incurs token cost and sends DSL content to the LLM provider.",
|
|
49175
|
+
"idempotent": false,
|
|
49176
|
+
"idempotentNote": "LLM inference is non-deterministic \u2014 identical inputs may produce different findings across runs."
|
|
49177
|
+
}
|
|
49178
|
+
},
|
|
49179
|
+
"options": [
|
|
49180
|
+
{
|
|
49181
|
+
"name": "config",
|
|
49182
|
+
"schema": {
|
|
49183
|
+
"type": "string"
|
|
49184
|
+
},
|
|
49185
|
+
"file": {
|
|
49186
|
+
"mode": "read",
|
|
49187
|
+
"exists": false,
|
|
49188
|
+
"mediaType": "application/yaml",
|
|
49189
|
+
"encoding": "utf-8"
|
|
49190
|
+
}
|
|
49191
|
+
},
|
|
49192
|
+
{
|
|
49193
|
+
"name": "team",
|
|
49194
|
+
"schema": {
|
|
49195
|
+
"type": "string"
|
|
49196
|
+
}
|
|
49197
|
+
},
|
|
49198
|
+
{
|
|
49199
|
+
"name": "format",
|
|
49200
|
+
"schema": {
|
|
49201
|
+
"type": "string",
|
|
49202
|
+
"enum": [
|
|
49203
|
+
"text",
|
|
49204
|
+
"json",
|
|
49205
|
+
"markdown"
|
|
49206
|
+
],
|
|
49207
|
+
"default": "text"
|
|
49208
|
+
}
|
|
49209
|
+
},
|
|
49210
|
+
{
|
|
49211
|
+
"name": "scope",
|
|
49212
|
+
"schema": {
|
|
49213
|
+
"type": "string"
|
|
49214
|
+
}
|
|
49215
|
+
},
|
|
49216
|
+
{
|
|
49217
|
+
"name": "dry-run",
|
|
49218
|
+
"schema": {
|
|
49219
|
+
"type": "boolean",
|
|
49220
|
+
"default": false
|
|
49221
|
+
}
|
|
49222
|
+
},
|
|
49223
|
+
{
|
|
49224
|
+
"name": "adapter",
|
|
49225
|
+
"schema": {
|
|
49226
|
+
"type": "string"
|
|
49227
|
+
}
|
|
49228
|
+
},
|
|
49229
|
+
{
|
|
49230
|
+
"name": "model",
|
|
49231
|
+
"schema": {
|
|
49232
|
+
"type": "string"
|
|
49233
|
+
}
|
|
49234
|
+
},
|
|
49235
|
+
{
|
|
49236
|
+
"name": "fail-on",
|
|
49237
|
+
"schema": {
|
|
49238
|
+
"type": "string",
|
|
49239
|
+
"enum": [
|
|
49240
|
+
"info",
|
|
49241
|
+
"warning",
|
|
49242
|
+
"error",
|
|
49243
|
+
"critical"
|
|
49244
|
+
],
|
|
49245
|
+
"default": "critical"
|
|
49246
|
+
}
|
|
49247
|
+
},
|
|
49248
|
+
{
|
|
49249
|
+
"name": "output",
|
|
49250
|
+
"schema": {
|
|
49251
|
+
"type": "string"
|
|
49252
|
+
},
|
|
49253
|
+
"file": {
|
|
49254
|
+
"mode": "write",
|
|
49255
|
+
"encoding": "utf-8"
|
|
49256
|
+
}
|
|
49257
|
+
},
|
|
49258
|
+
{
|
|
49259
|
+
"name": "report-format",
|
|
49260
|
+
"schema": {
|
|
49261
|
+
"type": "string",
|
|
49262
|
+
"enum": [
|
|
49263
|
+
"text",
|
|
49264
|
+
"json",
|
|
49265
|
+
"markdown"
|
|
49266
|
+
],
|
|
49267
|
+
"default": "text"
|
|
49268
|
+
}
|
|
49269
|
+
}
|
|
49270
|
+
]
|
|
49271
|
+
},
|
|
49272
|
+
"generate": {
|
|
49273
|
+
"effects": {
|
|
49274
|
+
"riskLevel": "low",
|
|
49275
|
+
"writes": [
|
|
49276
|
+
{
|
|
49277
|
+
"target": "configured render, guardrail, and interface output paths",
|
|
49278
|
+
"description": "template files, guardrail binding files, and/or team interface files generated from DSL input",
|
|
49279
|
+
"overwrite": true,
|
|
49280
|
+
"idempotent": true,
|
|
49281
|
+
"idempotentNote": "Output is deterministic from DSL input, templates, policies, and bindings. Repeated runs produce identical files."
|
|
49282
|
+
}
|
|
49283
|
+
]
|
|
49284
|
+
},
|
|
49285
|
+
"options": [
|
|
49286
|
+
{
|
|
49287
|
+
"name": "config",
|
|
49288
|
+
"schema": {
|
|
49289
|
+
"type": "string"
|
|
49290
|
+
},
|
|
49291
|
+
"file": {
|
|
49292
|
+
"mode": "read",
|
|
49293
|
+
"exists": false,
|
|
49294
|
+
"mediaType": "application/yaml",
|
|
49295
|
+
"encoding": "utf-8"
|
|
49296
|
+
}
|
|
49297
|
+
},
|
|
49298
|
+
{
|
|
49299
|
+
"name": "team",
|
|
49300
|
+
"schema": {
|
|
49301
|
+
"type": "string"
|
|
49302
|
+
}
|
|
49303
|
+
},
|
|
49304
|
+
{
|
|
49305
|
+
"name": "check",
|
|
49306
|
+
"schema": {
|
|
49307
|
+
"type": "boolean",
|
|
49308
|
+
"default": false
|
|
49309
|
+
}
|
|
49310
|
+
},
|
|
49311
|
+
{
|
|
49312
|
+
"name": "binding",
|
|
49313
|
+
"schema": {
|
|
49314
|
+
"type": "string"
|
|
49315
|
+
},
|
|
49316
|
+
"repeatable": true
|
|
49317
|
+
},
|
|
49318
|
+
{
|
|
49319
|
+
"name": "output",
|
|
49320
|
+
"schema": {
|
|
49321
|
+
"type": "string"
|
|
49322
|
+
},
|
|
49323
|
+
"file": {
|
|
49324
|
+
"mode": "write",
|
|
49325
|
+
"mediaType": "application/yaml",
|
|
49326
|
+
"encoding": "utf-8"
|
|
49327
|
+
}
|
|
49328
|
+
},
|
|
49329
|
+
{
|
|
49330
|
+
"name": "format",
|
|
49331
|
+
"schema": {
|
|
49332
|
+
"type": "string",
|
|
49333
|
+
"enum": [
|
|
49334
|
+
"yaml",
|
|
49335
|
+
"json"
|
|
49336
|
+
],
|
|
49337
|
+
"default": "yaml"
|
|
49338
|
+
}
|
|
49339
|
+
},
|
|
49340
|
+
{
|
|
49341
|
+
"name": "dry-run",
|
|
49342
|
+
"schema": {
|
|
49343
|
+
"type": "boolean",
|
|
49344
|
+
"default": false
|
|
49345
|
+
}
|
|
49346
|
+
},
|
|
49347
|
+
{
|
|
49348
|
+
"name": "quiet",
|
|
49349
|
+
"schema": {
|
|
49350
|
+
"type": "boolean",
|
|
49351
|
+
"default": false
|
|
49352
|
+
}
|
|
49353
|
+
}
|
|
49354
|
+
]
|
|
49355
|
+
}
|
|
49356
|
+
};
|
|
49357
|
+
function deriveCommandPolicy(commandId, optionValues) {
|
|
49358
|
+
const def = commandDefinitions[commandId];
|
|
49359
|
+
if (!def) throw new Error(`Unknown command: ${commandId}`);
|
|
49360
|
+
const cmdDef = def;
|
|
49361
|
+
const options = {};
|
|
49362
|
+
const activeOptions = [];
|
|
49363
|
+
for (const optDef of cmdDef.options ?? []) {
|
|
49364
|
+
const value = optionValues[optDef.name];
|
|
49365
|
+
const specified = optDef.name in optionValues && value !== void 0;
|
|
49366
|
+
options[optDef.name] = { value, specified, definition: optDef };
|
|
49367
|
+
if (isOptionActive(optDef, value, specified)) {
|
|
49368
|
+
activeOptions.push(optDef.name);
|
|
49369
|
+
}
|
|
49370
|
+
}
|
|
49371
|
+
const policy = derivePolicy({
|
|
49372
|
+
commandId,
|
|
49373
|
+
commandEffects: cmdDef.effects,
|
|
49374
|
+
options,
|
|
49375
|
+
env: cmdDef.env
|
|
49376
|
+
});
|
|
49377
|
+
return { command: commandId, activeOptions, policy };
|
|
49378
|
+
}
|
|
49379
|
+
|
|
49380
|
+
// src/generated/cli-contract/program.ts
|
|
49381
|
+
function createProgram(handlers2, version) {
|
|
49382
|
+
const program2 = new Command();
|
|
49383
|
+
program2.name("agent-contracts").version(version, "-V, --version").description("Agent contracts tooling \u2014 validate, lint, render DSL files.");
|
|
49384
|
+
program2.option("--introspect", "Output derived policy as JSON without executing the command");
|
|
49385
|
+
program2.command("resolve").description("Resolve DSL (load + merge extends) and output YAML.").argument("[dir]", "Path to agent-contracts.yaml.").option("-c, --config <path>", "Path to agent-contracts.config.yaml.").option("--team <id>", "Limit to one team (multi-team config only).").option("--format <format>", "Output format.", "text").option("--expand-defaults", "Expand all Zod default values in output. Fields like required_validations, tags, and can_read_artifacts are written explicitly instead of relying on schema defaults.", false).action(async (dir, opts, cmd) => {
|
|
49386
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
49387
|
+
if (globalOpts.introspect) {
|
|
49388
|
+
const policy = deriveCommandPolicy("resolve", opts);
|
|
49389
|
+
console.log(JSON.stringify(policy, null, 2));
|
|
49390
|
+
return;
|
|
49391
|
+
}
|
|
49392
|
+
await handlers2.resolve(dir, opts, globalOpts);
|
|
49393
|
+
});
|
|
49394
|
+
program2.command("validate").description("Validate DSL against schema and check references.").argument("[dir]", "Path to agent-contracts.yaml.").option("-c, --config <path>", "Path to agent-contracts.config.yaml.").option("--team <id>", "Limit to one team (multi-team config only).").option("--format <format>", "Diagnostic output format.", "text").option("--quiet", "Suppress output on success.", false).option("--strict", "Treat warnings as errors.", false).action(async (dir, opts, cmd) => {
|
|
49395
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
49396
|
+
if (globalOpts.introspect) {
|
|
49397
|
+
const policy = deriveCommandPolicy("validate", opts);
|
|
49398
|
+
console.log(JSON.stringify(policy, null, 2));
|
|
49399
|
+
return;
|
|
49400
|
+
}
|
|
49401
|
+
await handlers2.validate(dir, opts, globalOpts);
|
|
49402
|
+
});
|
|
49403
|
+
program2.command("lint").description("Run semantic lint rules on resolved DSL.").argument("[dir]", "Path to agent-contracts.yaml.").option("-c, --config <path>", "Path to agent-contracts.config.yaml.").option("--team <id>", "Limit to one team (multi-team config only).").option("--format <format>", "Output format.", "text").option("--quiet", "Suppress output on success.", false).option("--strict", "Treat warnings as errors.", false).action(async (dir, opts, cmd) => {
|
|
49404
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
49405
|
+
if (globalOpts.introspect) {
|
|
49406
|
+
const policy = deriveCommandPolicy("lint", opts);
|
|
49407
|
+
console.log(JSON.stringify(policy, null, 2));
|
|
49408
|
+
return;
|
|
49409
|
+
}
|
|
49410
|
+
await handlers2.lint(dir, opts, globalOpts);
|
|
49411
|
+
});
|
|
49412
|
+
program2.command("render").description("(deprecated) Alias for 'generate templates'.").option("-c, --config <path>", "Path to agent-contracts.config.yaml.").option("--team <id>", "Limit to one team (multi-team config only).").option("--check", "Check for template drift without writing files.", false).option("--quiet", "Suppress output on success.", false).action(async (opts, cmd) => {
|
|
49413
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
49414
|
+
if (globalOpts.introspect) {
|
|
49415
|
+
const policy = deriveCommandPolicy("render", opts);
|
|
49416
|
+
console.log(JSON.stringify(policy, null, 2));
|
|
49417
|
+
return;
|
|
49418
|
+
}
|
|
49419
|
+
await handlers2.render(opts, globalOpts);
|
|
49420
|
+
});
|
|
49421
|
+
program2.command("check").description("Run full pipeline \u2014 resolve, validate, lint, render --check.").option("-c, --config <path>", "Path to agent-contracts.config.yaml.").option("--team <id>", "Limit to one team (multi-team config only).").option("--format <format>", "Diagnostic output format.", "text").option("--quiet", "Suppress output on success.", false).option("--strict", "Treat warnings as errors.", false).action(async (opts, cmd) => {
|
|
49422
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
49423
|
+
if (globalOpts.introspect) {
|
|
49424
|
+
const policy = deriveCommandPolicy("check", opts);
|
|
49425
|
+
console.log(JSON.stringify(policy, null, 2));
|
|
49426
|
+
return;
|
|
49427
|
+
}
|
|
49428
|
+
await handlers2.check(opts, globalOpts);
|
|
49429
|
+
});
|
|
49430
|
+
program2.command("score").description("Calculate DSL completeness score.").argument("[dir]", "Path to agent-contracts.yaml.").option("-c, --config <path>", "Path to agent-contracts.config.yaml.").option("--team <id>", "Limit to one team (multi-team config only).").option("--format <format>", "Output format.", "text").option("--threshold <number>", "Minimum score; exit 1 if below (for CI gates).").action(async (dir, opts, cmd) => {
|
|
49431
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
49432
|
+
if (globalOpts.introspect) {
|
|
49433
|
+
const policy = deriveCommandPolicy("score", opts);
|
|
49434
|
+
console.log(JSON.stringify(policy, null, 2));
|
|
49435
|
+
return;
|
|
49436
|
+
}
|
|
49437
|
+
await handlers2.score(dir, opts, globalOpts);
|
|
49438
|
+
});
|
|
49439
|
+
program2.command("audit").description("Run LLM-based semantic audit on DSL definitions and generated outputs.").argument("[type]", "Audit type to run: render (semantic diff of generated outputs vs DSL), dsl (design coherence review), prompt (generated prompt fidelity check), or all (run all three).").option("-c, --config <path>", "Path to agent-contracts.config.yaml.").option("--team <id>", "Limit to one team (multi-team config only).").option("--format <format>", "Output format.", "text").option("--scope <entities>", "Limit audit scope to specified entities (e.g. agents:architect,implementer).").option("--dry-run", "Output the audit prompt without calling LLM.", false).option("--adapter <name>", "SDK adapter to use for LLM calls (overrides config audit.adapter).").option("--model <name>", "LLM model override (overrides config audit.model).").option("--fail-on <level>", "Minimum finding severity that causes exit 10 (info|warning|error|critical).", "critical").option("-o, --output <file>", "Write result to a file instead of stdout.").option("--report-format <fmt>", "Alias for --format. When both are specified, --report-format takes precedence.", "text").action(async (type, opts, cmd) => {
|
|
49440
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
49441
|
+
if (globalOpts.introspect) {
|
|
49442
|
+
const policy = deriveCommandPolicy("audit", opts);
|
|
49443
|
+
console.log(JSON.stringify(policy, null, 2));
|
|
49444
|
+
return;
|
|
49445
|
+
}
|
|
49446
|
+
await handlers2.audit(type, opts, globalOpts);
|
|
49447
|
+
});
|
|
49448
|
+
program2.command("generate").description("Generate artifacts from DSL \u2014 templates, guardrails, and/or interface.").argument("[type]", "Type of artifacts to generate. Omit to run all targets.").option("-c, --config <path>", "Path to agent-contracts.config.yaml.").option("--team <id>", "Limit to one team (multi-team config only).").option("--check", "Check for template drift without writing files. Only applies to the templates target.", false).option("--binding <name...>", "Filter to specific software binding(s). Guardrails type only.").option("-o, --output <path>", "Output path for generated team interface. Interface type only.").option("--format <format>", "Output format for team interface (yaml or json). Interface type only.", "yaml").option("--dry-run", "Print what would be generated without writing files.", false).option("--quiet", "Suppress output on success.", false).action(async (type, opts, cmd) => {
|
|
49449
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
49450
|
+
if (globalOpts.introspect) {
|
|
49451
|
+
const policy = deriveCommandPolicy("generate", opts);
|
|
49452
|
+
console.log(JSON.stringify(policy, null, 2));
|
|
49453
|
+
return;
|
|
49454
|
+
}
|
|
49455
|
+
await handlers2.generate(type, opts, globalOpts);
|
|
49456
|
+
});
|
|
49457
|
+
return program2;
|
|
49458
|
+
}
|
|
49459
|
+
|
|
49460
|
+
// src/cli/handlers.ts
|
|
49461
|
+
import { writeFileSync as writeFileSync2 } from "fs";
|
|
49462
|
+
import { existsSync, readFileSync } from "fs";
|
|
49463
|
+
import { join as join3, dirname as dirname7 } from "path";
|
|
49464
|
+
import { resolve as pathResolve } from "path";
|
|
49465
|
+
import { access as access2 } from "fs/promises";
|
|
49466
|
+
import { stringify as stringify3, parse as parseYaml4 } from "yaml";
|
|
49467
|
+
|
|
48619
49468
|
// src/config/binding-loader.ts
|
|
48620
49469
|
import { readFile as readFile3 } from "fs/promises";
|
|
48621
49470
|
import { dirname as dirname4, resolve as resolve5 } from "path";
|
|
@@ -50191,85 +51040,6 @@ ${issues}`,
|
|
|
50191
51040
|
return results;
|
|
50192
51041
|
}
|
|
50193
51042
|
|
|
50194
|
-
// src/cli/commands/resolve.ts
|
|
50195
|
-
import { stringify } from "yaml";
|
|
50196
|
-
|
|
50197
|
-
// src/cli/multi-team.ts
|
|
50198
|
-
function isMultiTeamConfig(config) {
|
|
50199
|
-
return config.teams !== void 0 && Object.keys(config.teams).length > 0;
|
|
50200
|
-
}
|
|
50201
|
-
function getTeamEntries(config, teamFilter) {
|
|
50202
|
-
if (!config.teams) return [];
|
|
50203
|
-
const entries = Object.entries(config.teams);
|
|
50204
|
-
if (teamFilter) {
|
|
50205
|
-
const found = entries.filter(([k2]) => k2 === teamFilter);
|
|
50206
|
-
if (found.length === 0) {
|
|
50207
|
-
throw new Error(
|
|
50208
|
-
`Team "${teamFilter}" not found. Available teams: ${entries.map(([k2]) => k2).join(", ")}`
|
|
50209
|
-
);
|
|
50210
|
-
}
|
|
50211
|
-
return found;
|
|
50212
|
-
}
|
|
50213
|
-
return entries;
|
|
50214
|
-
}
|
|
50215
|
-
|
|
50216
|
-
// src/cli/commands/resolve.ts
|
|
50217
|
-
var DIR_DEFAULT = "agent-contracts.yaml";
|
|
50218
|
-
var resolveCommand = new Command("resolve").description("Resolve DSL (load + merge extends) and output YAML").argument("[dir]", "Path to agent-contracts.yaml", DIR_DEFAULT).option("-c, --config <path>", "Path to agent-contracts.config.yaml").option("--team <id>", "Limit to one team (multi-team config only)").option("--format <format>", "Output format (text|json)", "text").option("--expand-defaults", "Expand all Zod default values in output", false).action(
|
|
50219
|
-
async (dir, opts) => {
|
|
50220
|
-
try {
|
|
50221
|
-
const config = await loadConfig(opts.config);
|
|
50222
|
-
if (config !== null && isMultiTeamConfig(config)) {
|
|
50223
|
-
const teamEntries = getTeamEntries(config, opts.team);
|
|
50224
|
-
if (opts.format === "json") {
|
|
50225
|
-
const out = {};
|
|
50226
|
-
for (const [teamId, teamConfig] of teamEntries) {
|
|
50227
|
-
const result2 = await resolve4(teamConfig.dsl);
|
|
50228
|
-
let data2 = teamConfig.vars ? substituteVars(result2.data, teamConfig.vars) : result2.data;
|
|
50229
|
-
if (opts.expandDefaults) {
|
|
50230
|
-
data2 = expandDefaults(data2);
|
|
50231
|
-
}
|
|
50232
|
-
out[teamId] = data2;
|
|
50233
|
-
}
|
|
50234
|
-
process.stdout.write(JSON.stringify(out, null, 2) + "\n");
|
|
50235
|
-
} else {
|
|
50236
|
-
for (const [teamId, teamConfig] of teamEntries) {
|
|
50237
|
-
process.stdout.write(`
|
|
50238
|
-
--- Team: ${teamId} ---
|
|
50239
|
-
`);
|
|
50240
|
-
const result2 = await resolve4(teamConfig.dsl);
|
|
50241
|
-
let data2 = teamConfig.vars ? substituteVars(result2.data, teamConfig.vars) : result2.data;
|
|
50242
|
-
if (opts.expandDefaults) {
|
|
50243
|
-
data2 = expandDefaults(data2);
|
|
50244
|
-
}
|
|
50245
|
-
process.stdout.write(stringify(data2));
|
|
50246
|
-
}
|
|
50247
|
-
}
|
|
50248
|
-
return;
|
|
50249
|
-
}
|
|
50250
|
-
const dslPath = resolveDslPath(dir, DIR_DEFAULT, config);
|
|
50251
|
-
const result = await resolve4(dslPath);
|
|
50252
|
-
let data = config?.vars ? substituteVars(result.data, config.vars) : result.data;
|
|
50253
|
-
if (opts.expandDefaults) {
|
|
50254
|
-
data = expandDefaults(data);
|
|
50255
|
-
}
|
|
50256
|
-
if (opts.format === "json") {
|
|
50257
|
-
process.stdout.write(JSON.stringify(data, null, 2) + "\n");
|
|
50258
|
-
} else {
|
|
50259
|
-
process.stdout.write(stringify(data));
|
|
50260
|
-
}
|
|
50261
|
-
} catch (err) {
|
|
50262
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
50263
|
-
process.stderr.write(`Error: ${msg}
|
|
50264
|
-
`);
|
|
50265
|
-
process.exit(1);
|
|
50266
|
-
}
|
|
50267
|
-
}
|
|
50268
|
-
);
|
|
50269
|
-
|
|
50270
|
-
// src/cli/commands/validate.ts
|
|
50271
|
-
import { Command as Command2 } from "commander";
|
|
50272
|
-
|
|
50273
51043
|
// src/validator/schema-validator.ts
|
|
50274
51044
|
import Ajv from "ajv";
|
|
50275
51045
|
import { z as z18 } from "zod";
|
|
@@ -51391,107 +52161,6 @@ function validateHandoffSchemas(dsl) {
|
|
|
51391
52161
|
return diagnostics;
|
|
51392
52162
|
}
|
|
51393
52163
|
|
|
51394
|
-
// src/cli/format.ts
|
|
51395
|
-
function formatDiagnostics(diagnostics, options) {
|
|
51396
|
-
if (options.quiet && diagnostics.length === 0) return "";
|
|
51397
|
-
if (options.format === "json") {
|
|
51398
|
-
return JSON.stringify(diagnostics, null, 2);
|
|
51399
|
-
}
|
|
51400
|
-
return diagnostics.map((d2) => {
|
|
51401
|
-
const severity = d2.severity ?? d2.code ?? "error";
|
|
51402
|
-
const rule = d2.ruleId ?? d2.code ?? "";
|
|
51403
|
-
return `${d2.path}: ${severity} [${rule}] ${d2.message}`;
|
|
51404
|
-
}).join("\n");
|
|
51405
|
-
}
|
|
51406
|
-
|
|
51407
|
-
// src/cli/commands/validate.ts
|
|
51408
|
-
var DIR_DEFAULT2 = "agent-contracts.yaml";
|
|
51409
|
-
var validateCommand = new Command2("validate").description("Validate DSL against schema and check references").argument("[dir]", "Path to agent-contracts.yaml", DIR_DEFAULT2).option("-c, --config <path>", "Path to agent-contracts.config.yaml").option("--team <id>", "Limit to one team (multi-team config only)").option("--format <format>", "Output format (text|json)", "text").option("--quiet", "Suppress output on success", false).option("--strict", "Treat warnings as errors", false).action(
|
|
51410
|
-
async (dir, opts) => {
|
|
51411
|
-
try {
|
|
51412
|
-
const config = await loadConfig(opts.config);
|
|
51413
|
-
if (config !== null && isMultiTeamConfig(config)) {
|
|
51414
|
-
const teamEntries = getTeamEntries(config, opts.team);
|
|
51415
|
-
let hasErrors = false;
|
|
51416
|
-
let allTeamsFullyClean = true;
|
|
51417
|
-
for (const [teamId, teamConfig] of teamEntries) {
|
|
51418
|
-
if (!opts.quiet) process.stdout.write(`
|
|
51419
|
-
--- Team: ${teamId} ---
|
|
51420
|
-
`);
|
|
51421
|
-
const resolved2 = await resolve4(teamConfig.dsl);
|
|
51422
|
-
const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
|
|
51423
|
-
const schemaResult2 = validateSchema(data2);
|
|
51424
|
-
const schemaWarnings2 = schemaResult2.diagnostics.filter(
|
|
51425
|
-
(d2) => d2.severity === "warning"
|
|
51426
|
-
);
|
|
51427
|
-
if (!schemaResult2.success) {
|
|
51428
|
-
const output = formatDiagnostics(schemaResult2.diagnostics, opts);
|
|
51429
|
-
if (output) process.stderr.write(output + "\n");
|
|
51430
|
-
hasErrors = true;
|
|
51431
|
-
allTeamsFullyClean = false;
|
|
51432
|
-
continue;
|
|
51433
|
-
}
|
|
51434
|
-
const refDiags2 = checkReferences(schemaResult2.data);
|
|
51435
|
-
const handoffDiags2 = validateHandoffSchemas(schemaResult2.data);
|
|
51436
|
-
const allDiags2 = [...refDiags2, ...handoffDiags2, ...schemaWarnings2];
|
|
51437
|
-
const hasWarnings2 = allDiags2.some(
|
|
51438
|
-
(d2) => "severity" in d2 && d2.severity === "warning"
|
|
51439
|
-
);
|
|
51440
|
-
if (allDiags2.length > 0) {
|
|
51441
|
-
allTeamsFullyClean = false;
|
|
51442
|
-
const output = formatDiagnostics(allDiags2, opts);
|
|
51443
|
-
if (output) process.stderr.write(output + "\n");
|
|
51444
|
-
if (refDiags2.length > 0 || handoffDiags2.length > 0 || opts.strict && hasWarnings2) {
|
|
51445
|
-
hasErrors = true;
|
|
51446
|
-
}
|
|
51447
|
-
}
|
|
51448
|
-
}
|
|
51449
|
-
if (hasErrors) process.exit(1);
|
|
51450
|
-
if (!opts.quiet && allTeamsFullyClean) {
|
|
51451
|
-
process.stdout.write("Validation passed.\n");
|
|
51452
|
-
}
|
|
51453
|
-
return;
|
|
51454
|
-
}
|
|
51455
|
-
const dslPath = resolveDslPath(dir, DIR_DEFAULT2, config);
|
|
51456
|
-
const resolved = await resolve4(dslPath);
|
|
51457
|
-
const data = config?.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
51458
|
-
const schemaResult = validateSchema(data);
|
|
51459
|
-
const schemaWarnings = schemaResult.diagnostics.filter(
|
|
51460
|
-
(d2) => d2.severity === "warning"
|
|
51461
|
-
);
|
|
51462
|
-
if (!schemaResult.success) {
|
|
51463
|
-
const output = formatDiagnostics(schemaResult.diagnostics, opts);
|
|
51464
|
-
if (output) process.stderr.write(output + "\n");
|
|
51465
|
-
process.exit(1);
|
|
51466
|
-
}
|
|
51467
|
-
const refDiags = checkReferences(schemaResult.data);
|
|
51468
|
-
const handoffDiags = validateHandoffSchemas(schemaResult.data);
|
|
51469
|
-
const allDiags = [...refDiags, ...handoffDiags, ...schemaWarnings];
|
|
51470
|
-
const hasWarnings = allDiags.some(
|
|
51471
|
-
(d2) => "severity" in d2 && d2.severity === "warning"
|
|
51472
|
-
);
|
|
51473
|
-
if (allDiags.length > 0) {
|
|
51474
|
-
const output = formatDiagnostics(allDiags, opts);
|
|
51475
|
-
if (output) process.stderr.write(output + "\n");
|
|
51476
|
-
if (refDiags.length > 0 || handoffDiags.length > 0 || opts.strict && hasWarnings) {
|
|
51477
|
-
process.exit(1);
|
|
51478
|
-
}
|
|
51479
|
-
}
|
|
51480
|
-
if (!opts.quiet && allDiags.length === 0) {
|
|
51481
|
-
process.stdout.write("Validation passed.\n");
|
|
51482
|
-
}
|
|
51483
|
-
} catch (err) {
|
|
51484
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
51485
|
-
process.stderr.write(`Error: ${msg}
|
|
51486
|
-
`);
|
|
51487
|
-
process.exit(1);
|
|
51488
|
-
}
|
|
51489
|
-
}
|
|
51490
|
-
);
|
|
51491
|
-
|
|
51492
|
-
// src/cli/commands/lint.ts
|
|
51493
|
-
import { Command as Command3 } from "commander";
|
|
51494
|
-
|
|
51495
52164
|
// src/linter/rules/validation-coverage.ts
|
|
51496
52165
|
var validationCoverageRule = {
|
|
51497
52166
|
id: "validation-coverage",
|
|
@@ -52251,7 +52920,7 @@ function lint(dsl, rules = builtinRules) {
|
|
|
52251
52920
|
var import_spectral_core7 = __toESM(require_dist9(), 1);
|
|
52252
52921
|
|
|
52253
52922
|
// src/linter/spectral/ruleset.ts
|
|
52254
|
-
var import_spectral_functions = __toESM(
|
|
52923
|
+
var import_spectral_functions = __toESM(require_dist14(), 1);
|
|
52255
52924
|
|
|
52256
52925
|
// src/linter/spectral/functions/ref-exists.ts
|
|
52257
52926
|
var import_spectral_core = __toESM(require_dist9(), 1);
|
|
@@ -52883,110 +53552,6 @@ async function spectralLint(dslObject) {
|
|
|
52883
53552
|
}));
|
|
52884
53553
|
}
|
|
52885
53554
|
|
|
52886
|
-
// src/cli/commands/lint.ts
|
|
52887
|
-
var DIR_DEFAULT3 = "agent-contracts.yaml";
|
|
52888
|
-
var lintCommand = new Command3("lint").description("Run semantic lint rules on resolved DSL").argument("[dir]", "Path to agent-contracts.yaml", DIR_DEFAULT3).option("-c, --config <path>", "Path to agent-contracts.config.yaml").option("--team <id>", "Limit to one team (multi-team config only)").option("--format <format>", "Output format (text|json)", "text").option("--quiet", "Suppress output on success", false).option("--strict", "Treat warnings as errors", false).action(
|
|
52889
|
-
async (dir, opts) => {
|
|
52890
|
-
try {
|
|
52891
|
-
const config = await loadConfig(opts.config);
|
|
52892
|
-
if (config !== null && isMultiTeamConfig(config)) {
|
|
52893
|
-
const teamEntries = getTeamEntries(config, opts.team);
|
|
52894
|
-
let hasErrors = false;
|
|
52895
|
-
let allClean = true;
|
|
52896
|
-
for (const [teamId, teamConfig] of teamEntries) {
|
|
52897
|
-
if (!opts.quiet) process.stdout.write(`
|
|
52898
|
-
--- Team: ${teamId} ---
|
|
52899
|
-
`);
|
|
52900
|
-
const resolved2 = await resolve4(teamConfig.dsl);
|
|
52901
|
-
const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
|
|
52902
|
-
const schemaResult2 = validateSchema(data2);
|
|
52903
|
-
const schemaWarnings2 = schemaResult2.diagnostics.filter(
|
|
52904
|
-
(d2) => d2.severity === "warning"
|
|
52905
|
-
);
|
|
52906
|
-
if (!schemaResult2.success) {
|
|
52907
|
-
const output = formatDiagnostics(schemaResult2.diagnostics, {
|
|
52908
|
-
format: opts.format,
|
|
52909
|
-
quiet: opts.quiet
|
|
52910
|
-
});
|
|
52911
|
-
if (output) process.stderr.write(output + "\n");
|
|
52912
|
-
hasErrors = true;
|
|
52913
|
-
allClean = false;
|
|
52914
|
-
continue;
|
|
52915
|
-
}
|
|
52916
|
-
const tsDiagnostics2 = lint(schemaResult2.data);
|
|
52917
|
-
const spectralDiagnostics2 = await spectralLint(
|
|
52918
|
-
schemaResult2.data
|
|
52919
|
-
);
|
|
52920
|
-
const diagnostics2 = [
|
|
52921
|
-
...tsDiagnostics2,
|
|
52922
|
-
...spectralDiagnostics2,
|
|
52923
|
-
...schemaWarnings2
|
|
52924
|
-
];
|
|
52925
|
-
if (diagnostics2.length > 0) {
|
|
52926
|
-
allClean = false;
|
|
52927
|
-
const output = formatDiagnostics(diagnostics2, {
|
|
52928
|
-
format: opts.format,
|
|
52929
|
-
quiet: opts.quiet
|
|
52930
|
-
});
|
|
52931
|
-
if (output) process.stderr.write(output + "\n");
|
|
52932
|
-
const teamHasErrors = diagnostics2.some((d2) => d2.severity === "error");
|
|
52933
|
-
const teamHasWarnings = diagnostics2.some((d2) => d2.severity === "warning");
|
|
52934
|
-
if (teamHasErrors || opts.strict && teamHasWarnings) {
|
|
52935
|
-
hasErrors = true;
|
|
52936
|
-
}
|
|
52937
|
-
}
|
|
52938
|
-
}
|
|
52939
|
-
if (hasErrors) process.exit(1);
|
|
52940
|
-
if (!opts.quiet && allClean) {
|
|
52941
|
-
process.stdout.write("Lint passed.\n");
|
|
52942
|
-
}
|
|
52943
|
-
return;
|
|
52944
|
-
}
|
|
52945
|
-
const dslPath = resolveDslPath(dir, DIR_DEFAULT3, config);
|
|
52946
|
-
const resolved = await resolve4(dslPath);
|
|
52947
|
-
const data = config?.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
52948
|
-
const schemaResult = validateSchema(data);
|
|
52949
|
-
const schemaWarnings = schemaResult.diagnostics.filter(
|
|
52950
|
-
(d2) => d2.severity === "warning"
|
|
52951
|
-
);
|
|
52952
|
-
if (!schemaResult.success) {
|
|
52953
|
-
const output = formatDiagnostics(schemaResult.diagnostics, {
|
|
52954
|
-
format: opts.format,
|
|
52955
|
-
quiet: opts.quiet
|
|
52956
|
-
});
|
|
52957
|
-
if (output) process.stderr.write(output + "\n");
|
|
52958
|
-
process.exit(1);
|
|
52959
|
-
}
|
|
52960
|
-
const tsDiagnostics = lint(schemaResult.data);
|
|
52961
|
-
const spectralDiagnostics = await spectralLint(schemaResult.data);
|
|
52962
|
-
const diagnostics = [...tsDiagnostics, ...spectralDiagnostics, ...schemaWarnings];
|
|
52963
|
-
if (diagnostics.length > 0) {
|
|
52964
|
-
const output = formatDiagnostics(diagnostics, {
|
|
52965
|
-
format: opts.format,
|
|
52966
|
-
quiet: opts.quiet
|
|
52967
|
-
});
|
|
52968
|
-
if (output) process.stderr.write(output + "\n");
|
|
52969
|
-
const hasErrors = diagnostics.some((d2) => d2.severity === "error");
|
|
52970
|
-
const hasWarnings = diagnostics.some((d2) => d2.severity === "warning");
|
|
52971
|
-
if (hasErrors || opts.strict && hasWarnings) {
|
|
52972
|
-
process.exit(1);
|
|
52973
|
-
}
|
|
52974
|
-
}
|
|
52975
|
-
if (!opts.quiet && diagnostics.length === 0) {
|
|
52976
|
-
process.stdout.write("Lint passed.\n");
|
|
52977
|
-
}
|
|
52978
|
-
} catch (err) {
|
|
52979
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
52980
|
-
process.stderr.write(`Error: ${msg}
|
|
52981
|
-
`);
|
|
52982
|
-
process.exit(1);
|
|
52983
|
-
}
|
|
52984
|
-
}
|
|
52985
|
-
);
|
|
52986
|
-
|
|
52987
|
-
// src/cli/commands/render.ts
|
|
52988
|
-
import { Command as Command4 } from "commander";
|
|
52989
|
-
|
|
52990
53555
|
// src/renderer/renderer.ts
|
|
52991
53556
|
import { readFile as readFile4, writeFile, mkdir, unlink } from "fs/promises";
|
|
52992
53557
|
import { dirname as dirname5 } from "path";
|
|
@@ -54380,458 +54945,321 @@ async function checkDriftFromConfig(dsl, renderTargets, options) {
|
|
|
54380
54945
|
return { hasDrift: diffs.length > 0, diffs };
|
|
54381
54946
|
}
|
|
54382
54947
|
|
|
54383
|
-
// src/
|
|
54384
|
-
|
|
54385
|
-
|
|
54386
|
-
|
|
54387
|
-
|
|
54388
|
-
|
|
54389
|
-
|
|
54390
|
-
|
|
54391
|
-
|
|
54392
|
-
|
|
54948
|
+
// src/scorer/scorer.ts
|
|
54949
|
+
function pct(n3, d2) {
|
|
54950
|
+
return d2 === 0 ? 100 : Math.round(n3 / d2 * 100);
|
|
54951
|
+
}
|
|
54952
|
+
function artifactValidationCoverage(dsl) {
|
|
54953
|
+
const entries = Object.entries(dsl.artifacts);
|
|
54954
|
+
const total = entries.length;
|
|
54955
|
+
const covered = entries.filter(
|
|
54956
|
+
([, a3]) => a3.required_validations.length > 0
|
|
54957
|
+
).length;
|
|
54958
|
+
const missing = entries.filter(([, a3]) => a3.required_validations.length === 0).map(([id]) => id);
|
|
54959
|
+
return {
|
|
54960
|
+
id: "artifact-validation-coverage",
|
|
54961
|
+
label: "Artifact validation coverage",
|
|
54962
|
+
score: covered,
|
|
54963
|
+
total,
|
|
54964
|
+
percent: pct(covered, total),
|
|
54965
|
+
weight: 3,
|
|
54966
|
+
recommendations: missing.length > 0 ? [`${missing.length} artifacts missing required_validations: ${missing.join(", ")}`] : []
|
|
54967
|
+
};
|
|
54968
|
+
}
|
|
54969
|
+
function taskValidationCoverage(dsl) {
|
|
54970
|
+
const entries = Object.entries(dsl.tasks);
|
|
54971
|
+
const total = entries.length;
|
|
54972
|
+
const covered = entries.filter(([, t3]) => t3.validations.length > 0).length;
|
|
54973
|
+
const missing = entries.filter(([, t3]) => t3.validations.length === 0).map(([id]) => id);
|
|
54974
|
+
return {
|
|
54975
|
+
id: "task-validation-coverage",
|
|
54976
|
+
label: "Task validation coverage",
|
|
54977
|
+
score: covered,
|
|
54978
|
+
total,
|
|
54979
|
+
percent: pct(covered, total),
|
|
54980
|
+
weight: 3,
|
|
54981
|
+
recommendations: missing.length > 0 ? [`${missing.length} tasks missing validations: ${missing.join(", ")}`] : []
|
|
54982
|
+
};
|
|
54983
|
+
}
|
|
54984
|
+
function guardrailPolicyCoverage(dsl) {
|
|
54985
|
+
const guardrailIds = Object.keys(dsl.guardrails);
|
|
54986
|
+
const total = guardrailIds.length;
|
|
54987
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
54988
|
+
for (const policy of Object.values(dsl.guardrail_policies)) {
|
|
54989
|
+
for (const rule of policy.rules) {
|
|
54990
|
+
referenced.add(rule.guardrail);
|
|
54991
|
+
}
|
|
54992
|
+
}
|
|
54993
|
+
const covered = guardrailIds.filter((id) => referenced.has(id)).length;
|
|
54994
|
+
const missing = guardrailIds.filter((id) => !referenced.has(id));
|
|
54995
|
+
return {
|
|
54996
|
+
id: "guardrail-policy-coverage",
|
|
54997
|
+
label: "Guardrail policy coverage",
|
|
54998
|
+
score: covered,
|
|
54999
|
+
total,
|
|
55000
|
+
percent: pct(covered, total),
|
|
55001
|
+
weight: 2,
|
|
55002
|
+
recommendations: missing.length > 0 ? [`${missing.length} guardrails not in any policy: ${missing.join(", ")}`] : []
|
|
55003
|
+
};
|
|
55004
|
+
}
|
|
55005
|
+
function workflowValidationIntegration(dsl) {
|
|
55006
|
+
const blockingValidations = Object.entries(dsl.validations).filter(
|
|
55007
|
+
([, v2]) => v2.blocking
|
|
55008
|
+
);
|
|
55009
|
+
const total = blockingValidations.length;
|
|
55010
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
55011
|
+
for (const wf of Object.values(dsl.workflow)) {
|
|
55012
|
+
for (const step of wf.steps) {
|
|
55013
|
+
if (step.type === "validation") {
|
|
55014
|
+
referenced.add(step.validation);
|
|
54393
55015
|
}
|
|
54394
|
-
|
|
54395
|
-
|
|
54396
|
-
|
|
54397
|
-
|
|
54398
|
-
|
|
54399
|
-
|
|
54400
|
-
|
|
54401
|
-
|
|
54402
|
-
|
|
54403
|
-
|
|
54404
|
-
|
|
54405
|
-
|
|
54406
|
-
|
|
54407
|
-
|
|
54408
|
-
|
|
54409
|
-
|
|
54410
|
-
|
|
54411
|
-
|
|
54412
|
-
|
|
54413
|
-
|
|
54414
|
-
|
|
54415
|
-
|
|
54416
|
-
|
|
54417
|
-
|
|
54418
|
-
|
|
54419
|
-
|
|
54420
|
-
|
|
54421
|
-
|
|
54422
|
-
|
|
54423
|
-
|
|
54424
|
-
|
|
54425
|
-
|
|
54426
|
-
|
|
54427
|
-
|
|
54428
|
-
|
|
54429
|
-
|
|
54430
|
-
|
|
54431
|
-
|
|
54432
|
-
|
|
54433
|
-
|
|
54434
|
-
|
|
54435
|
-
|
|
54436
|
-
|
|
54437
|
-
|
|
54438
|
-
|
|
54439
|
-
|
|
54440
|
-
|
|
54441
|
-
|
|
54442
|
-
|
|
54443
|
-
|
|
54444
|
-
|
|
54445
|
-
|
|
54446
|
-
|
|
54447
|
-
|
|
54448
|
-
|
|
54449
|
-
|
|
54450
|
-
|
|
54451
|
-
|
|
54452
|
-
|
|
55016
|
+
}
|
|
55017
|
+
}
|
|
55018
|
+
for (const task of Object.values(dsl.tasks)) {
|
|
55019
|
+
for (const valId of task.validations) {
|
|
55020
|
+
referenced.add(valId);
|
|
55021
|
+
}
|
|
55022
|
+
}
|
|
55023
|
+
const covered = blockingValidations.filter(
|
|
55024
|
+
([id]) => referenced.has(id)
|
|
55025
|
+
).length;
|
|
55026
|
+
const missing = blockingValidations.filter(([id]) => !referenced.has(id)).map(([id]) => id);
|
|
55027
|
+
return {
|
|
55028
|
+
id: "workflow-validation-integration",
|
|
55029
|
+
label: "Workflow validation integration",
|
|
55030
|
+
score: covered,
|
|
55031
|
+
total,
|
|
55032
|
+
percent: pct(covered, total),
|
|
55033
|
+
weight: 3,
|
|
55034
|
+
recommendations: missing.length > 0 ? [`${missing.length} blocking validations not wired: ${missing.join(", ")}`] : []
|
|
55035
|
+
};
|
|
55036
|
+
}
|
|
55037
|
+
var OPTIONAL_ENTITY_FIELDS = {
|
|
55038
|
+
agents: {
|
|
55039
|
+
section: "agents",
|
|
55040
|
+
fields: ["responsibilities", "constraints", "rules"]
|
|
55041
|
+
},
|
|
55042
|
+
tasks: {
|
|
55043
|
+
section: "tasks",
|
|
55044
|
+
fields: ["description", "responsibilities", "execution_steps", "completion_criteria"]
|
|
55045
|
+
},
|
|
55046
|
+
artifacts: {
|
|
55047
|
+
section: "artifacts",
|
|
55048
|
+
fields: ["description", "visibility"]
|
|
55049
|
+
},
|
|
55050
|
+
tools: {
|
|
55051
|
+
section: "tools",
|
|
55052
|
+
fields: ["description", "commands"]
|
|
55053
|
+
},
|
|
55054
|
+
workflow: {
|
|
55055
|
+
section: "workflow",
|
|
55056
|
+
fields: ["description", "trigger", "entry_conditions"]
|
|
55057
|
+
},
|
|
55058
|
+
guardrails: {
|
|
55059
|
+
section: "guardrails",
|
|
55060
|
+
fields: ["rationale", "tags"]
|
|
55061
|
+
}
|
|
55062
|
+
};
|
|
55063
|
+
function hasNonEmpty(obj, field) {
|
|
55064
|
+
const val = obj[field];
|
|
55065
|
+
if (val === void 0 || val === null) return false;
|
|
55066
|
+
if (typeof val === "string") return val.length > 0;
|
|
55067
|
+
if (Array.isArray(val)) return val.length > 0;
|
|
55068
|
+
return true;
|
|
55069
|
+
}
|
|
55070
|
+
function schemaCompleteness(dsl) {
|
|
55071
|
+
let totalSlots = 0;
|
|
55072
|
+
let filledSlots = 0;
|
|
55073
|
+
const lowSections = [];
|
|
55074
|
+
for (const [sectionKey, meta] of Object.entries(OPTIONAL_ENTITY_FIELDS)) {
|
|
55075
|
+
const entities = dsl[meta.section];
|
|
55076
|
+
if (!entities) continue;
|
|
55077
|
+
let sectionTotal = 0;
|
|
55078
|
+
let sectionFilled = 0;
|
|
55079
|
+
for (const entity of Object.values(entities)) {
|
|
55080
|
+
for (const field of meta.fields) {
|
|
55081
|
+
sectionTotal++;
|
|
55082
|
+
totalSlots++;
|
|
55083
|
+
if (hasNonEmpty(entity, field)) {
|
|
55084
|
+
sectionFilled++;
|
|
55085
|
+
filledSlots++;
|
|
54453
55086
|
}
|
|
54454
|
-
return;
|
|
54455
55087
|
}
|
|
54456
|
-
|
|
54457
|
-
|
|
54458
|
-
|
|
54459
|
-
|
|
54460
|
-
|
|
54461
|
-
|
|
54462
|
-
|
|
54463
|
-
|
|
55088
|
+
}
|
|
55089
|
+
if (sectionTotal > 0 && pct(sectionFilled, sectionTotal) < 50) {
|
|
55090
|
+
lowSections.push(sectionKey);
|
|
55091
|
+
}
|
|
55092
|
+
}
|
|
55093
|
+
return {
|
|
55094
|
+
id: "schema-completeness",
|
|
55095
|
+
label: "Schema completeness",
|
|
55096
|
+
score: filledSlots,
|
|
55097
|
+
total: totalSlots,
|
|
55098
|
+
percent: pct(filledSlots, totalSlots),
|
|
55099
|
+
weight: 1,
|
|
55100
|
+
recommendations: lowSections.length > 0 ? [`Low optional field coverage in: ${lowSections.join(", ")}`] : []
|
|
55101
|
+
};
|
|
55102
|
+
}
|
|
55103
|
+
function crossReferenceBidirectionality(dsl) {
|
|
55104
|
+
let totalChecks = 0;
|
|
55105
|
+
let passedChecks = 0;
|
|
55106
|
+
const issues = [];
|
|
55107
|
+
for (const [agentId, agent] of Object.entries(dsl.agents)) {
|
|
55108
|
+
for (const toolId of agent.can_execute_tools) {
|
|
55109
|
+
totalChecks++;
|
|
55110
|
+
const tool = dsl.tools[toolId];
|
|
55111
|
+
if (tool && tool.invokable_by.includes(agentId)) {
|
|
55112
|
+
passedChecks++;
|
|
55113
|
+
} else {
|
|
55114
|
+
issues.push(`agent ${agentId} \u2192 tool ${toolId}`);
|
|
54464
55115
|
}
|
|
54465
|
-
|
|
54466
|
-
|
|
54467
|
-
|
|
54468
|
-
|
|
54469
|
-
|
|
54470
|
-
|
|
54471
|
-
|
|
55116
|
+
}
|
|
55117
|
+
for (const artId of agent.can_write_artifacts) {
|
|
55118
|
+
totalChecks++;
|
|
55119
|
+
const art = dsl.artifacts[artId];
|
|
55120
|
+
if (art && (art.producers.includes(agentId) || art.editors.includes(agentId))) {
|
|
55121
|
+
passedChecks++;
|
|
55122
|
+
} else {
|
|
55123
|
+
issues.push(`agent ${agentId} \u2192 artifact ${artId} (write)`);
|
|
54472
55124
|
}
|
|
54473
|
-
|
|
54474
|
-
|
|
54475
|
-
|
|
54476
|
-
|
|
54477
|
-
|
|
54478
|
-
|
|
54479
|
-
if (drift.hasDrift) {
|
|
54480
|
-
process.stderr.write("Drift detected in the following files:\n");
|
|
54481
|
-
for (const f2 of drift.diffs) {
|
|
54482
|
-
process.stderr.write(` ${f2}
|
|
54483
|
-
`);
|
|
54484
|
-
}
|
|
54485
|
-
process.exit(1);
|
|
54486
|
-
}
|
|
54487
|
-
if (!opts.quiet) {
|
|
54488
|
-
process.stdout.write("No drift detected.\n");
|
|
54489
|
-
}
|
|
55125
|
+
}
|
|
55126
|
+
for (const artId of agent.can_read_artifacts) {
|
|
55127
|
+
totalChecks++;
|
|
55128
|
+
const art = dsl.artifacts[artId];
|
|
55129
|
+
if (art && (art.consumers.includes(agentId) || art.producers.includes(agentId) || art.editors.includes(agentId))) {
|
|
55130
|
+
passedChecks++;
|
|
54490
55131
|
} else {
|
|
54491
|
-
|
|
54492
|
-
schemaResult.data,
|
|
54493
|
-
config.renders,
|
|
54494
|
-
renderOptions
|
|
54495
|
-
);
|
|
54496
|
-
if (!opts.quiet) {
|
|
54497
|
-
process.stdout.write(`Rendered ${files.length} file(s):
|
|
54498
|
-
`);
|
|
54499
|
-
for (const f2 of files) {
|
|
54500
|
-
process.stdout.write(` ${f2}
|
|
54501
|
-
`);
|
|
54502
|
-
}
|
|
54503
|
-
}
|
|
55132
|
+
issues.push(`agent ${agentId} \u2192 artifact ${artId} (read)`);
|
|
54504
55133
|
}
|
|
54505
|
-
}
|
|
54506
|
-
|
|
54507
|
-
|
|
54508
|
-
|
|
54509
|
-
|
|
55134
|
+
}
|
|
55135
|
+
}
|
|
55136
|
+
for (const [toolId, tool] of Object.entries(dsl.tools)) {
|
|
55137
|
+
for (const agentId of tool.invokable_by) {
|
|
55138
|
+
totalChecks++;
|
|
55139
|
+
const agent = dsl.agents[agentId];
|
|
55140
|
+
if (agent && agent.can_execute_tools.includes(toolId)) {
|
|
55141
|
+
passedChecks++;
|
|
55142
|
+
} else {
|
|
55143
|
+
issues.push(`tool ${toolId} \u2192 agent ${agentId}`);
|
|
54510
55144
|
}
|
|
54511
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
54512
|
-
process.stderr.write(`Error: ${msg}
|
|
54513
|
-
`);
|
|
54514
|
-
process.exit(1);
|
|
54515
55145
|
}
|
|
54516
55146
|
}
|
|
54517
|
-
|
|
54518
|
-
|
|
54519
|
-
|
|
54520
|
-
|
|
54521
|
-
|
|
54522
|
-
|
|
54523
|
-
|
|
54524
|
-
|
|
54525
|
-
import { resolve as pathResolve, dirname as dirname6 } from "path";
|
|
54526
|
-
|
|
54527
|
-
// src/interface-generator/generator.ts
|
|
54528
|
-
import { stringify as stringify2 } from "yaml";
|
|
54529
|
-
function buildInterfaceDocument(dsl, generatedAt) {
|
|
54530
|
-
const ti = dsl.team_interface;
|
|
54531
|
-
const doc = {
|
|
54532
|
-
team_id: dsl.system.id,
|
|
54533
|
-
team_name: dsl.system.name,
|
|
54534
|
-
version: ti.version,
|
|
54535
|
-
generated_at: generatedAt
|
|
55147
|
+
return {
|
|
55148
|
+
id: "cross-reference-bidirectionality",
|
|
55149
|
+
label: "Cross-reference bidirectionality",
|
|
55150
|
+
score: passedChecks,
|
|
55151
|
+
total: totalChecks,
|
|
55152
|
+
percent: pct(passedChecks, totalChecks),
|
|
55153
|
+
weight: 2,
|
|
55154
|
+
recommendations: issues.length > 0 ? [`${issues.length} unreciprocated cross-references: ${issues.slice(0, 5).join(", ")}${issues.length > 5 ? `, ... (${issues.length - 5} more)` : ""}`] : []
|
|
54536
55155
|
};
|
|
54537
|
-
|
|
54538
|
-
|
|
54539
|
-
|
|
54540
|
-
|
|
54541
|
-
|
|
54542
|
-
|
|
54543
|
-
|
|
54544
|
-
|
|
54545
|
-
|
|
54546
|
-
|
|
54547
|
-
|
|
55156
|
+
}
|
|
55157
|
+
function entityGuardrailCoverage(dsl) {
|
|
55158
|
+
const entitySections = [
|
|
55159
|
+
{ name: "agents", entities: dsl.agents },
|
|
55160
|
+
{ name: "tasks", entities: dsl.tasks },
|
|
55161
|
+
{ name: "tools", entities: dsl.tools },
|
|
55162
|
+
{ name: "artifacts", entities: dsl.artifacts }
|
|
55163
|
+
];
|
|
55164
|
+
const scopeBindings = {
|
|
55165
|
+
agents: /* @__PURE__ */ new Set(),
|
|
55166
|
+
tasks: /* @__PURE__ */ new Set(),
|
|
55167
|
+
tools: /* @__PURE__ */ new Set(),
|
|
55168
|
+
artifacts: /* @__PURE__ */ new Set()
|
|
55169
|
+
};
|
|
55170
|
+
for (const guardrail of Object.values(dsl.guardrails)) {
|
|
55171
|
+
for (const key of Object.keys(scopeBindings)) {
|
|
55172
|
+
const ids = guardrail.scope[key];
|
|
55173
|
+
if (ids) {
|
|
55174
|
+
for (const id of ids) scopeBindings[key].add(id);
|
|
55175
|
+
}
|
|
54548
55176
|
}
|
|
54549
55177
|
}
|
|
54550
|
-
|
|
54551
|
-
|
|
54552
|
-
|
|
54553
|
-
|
|
54554
|
-
|
|
54555
|
-
|
|
54556
|
-
|
|
54557
|
-
|
|
54558
|
-
if (
|
|
54559
|
-
|
|
55178
|
+
let total = 0;
|
|
55179
|
+
let covered = 0;
|
|
55180
|
+
const missing = [];
|
|
55181
|
+
for (const { name, entities } of entitySections) {
|
|
55182
|
+
for (const [entityId, entity] of Object.entries(entities)) {
|
|
55183
|
+
total++;
|
|
55184
|
+
const hasEntitySide = (entity.guardrails ?? []).length > 0;
|
|
55185
|
+
const hasScopeSide = scopeBindings[name].has(entityId);
|
|
55186
|
+
if (hasEntitySide || hasScopeSide) {
|
|
55187
|
+
covered++;
|
|
55188
|
+
} else {
|
|
55189
|
+
missing.push(`${name}.${entityId}`);
|
|
54560
55190
|
}
|
|
54561
|
-
handoff_types[k2] = entry;
|
|
54562
55191
|
}
|
|
54563
55192
|
}
|
|
54564
|
-
|
|
54565
|
-
|
|
54566
|
-
|
|
54567
|
-
|
|
54568
|
-
|
|
54569
|
-
|
|
54570
|
-
|
|
54571
|
-
|
|
54572
|
-
|
|
54573
|
-
|
|
54574
|
-
|
|
54575
|
-
|
|
54576
|
-
|
|
54577
|
-
|
|
55193
|
+
return {
|
|
55194
|
+
id: "entity-guardrail-coverage",
|
|
55195
|
+
label: "Entity guardrail coverage",
|
|
55196
|
+
score: covered,
|
|
55197
|
+
total,
|
|
55198
|
+
percent: pct(covered, total),
|
|
55199
|
+
weight: 1,
|
|
55200
|
+
recommendations: missing.length > 0 ? [`${missing.length} entities without guardrails: ${missing.slice(0, 5).join(", ")}${missing.length > 5 ? `, ... (${missing.length - 5} more)` : ""}`] : []
|
|
55201
|
+
};
|
|
55202
|
+
}
|
|
55203
|
+
function guardrailScopeResolution(dsl) {
|
|
55204
|
+
let totalRefs = 0;
|
|
55205
|
+
let resolvedRefs = 0;
|
|
55206
|
+
const unresolved = [];
|
|
55207
|
+
const sectionMap = {
|
|
55208
|
+
agents: dsl.agents,
|
|
55209
|
+
tasks: dsl.tasks,
|
|
55210
|
+
tools: dsl.tools,
|
|
55211
|
+
artifacts: dsl.artifacts,
|
|
55212
|
+
workflows: dsl.workflow
|
|
55213
|
+
};
|
|
55214
|
+
for (const [guardrailId, guardrail] of Object.entries(dsl.guardrails)) {
|
|
55215
|
+
const scope = guardrail.scope;
|
|
55216
|
+
for (const [scopeKey, entityIds] of Object.entries(scope)) {
|
|
55217
|
+
if (!Array.isArray(entityIds)) continue;
|
|
55218
|
+
const section = sectionMap[scopeKey];
|
|
55219
|
+
if (!section) continue;
|
|
55220
|
+
for (const entityId of entityIds) {
|
|
55221
|
+
totalRefs++;
|
|
55222
|
+
if (section[entityId]) {
|
|
55223
|
+
resolvedRefs++;
|
|
55224
|
+
} else {
|
|
55225
|
+
unresolved.push(`${guardrailId}.scope.${scopeKey}: ${entityId}`);
|
|
54578
55226
|
}
|
|
54579
|
-
artifactsOut[key] = entry;
|
|
54580
55227
|
}
|
|
54581
55228
|
}
|
|
54582
55229
|
}
|
|
54583
|
-
|
|
54584
|
-
|
|
54585
|
-
|
|
54586
|
-
|
|
54587
|
-
|
|
54588
|
-
|
|
54589
|
-
|
|
54590
|
-
}
|
|
54591
|
-
|
|
54592
|
-
|
|
54593
|
-
|
|
54594
|
-
|
|
54595
|
-
|
|
54596
|
-
|
|
54597
|
-
|
|
54598
|
-
|
|
54599
|
-
|
|
54600
|
-
|
|
55230
|
+
return {
|
|
55231
|
+
id: "guardrail-scope-resolution",
|
|
55232
|
+
label: "Guardrail scope resolution",
|
|
55233
|
+
score: resolvedRefs,
|
|
55234
|
+
total: totalRefs,
|
|
55235
|
+
percent: pct(resolvedRefs, totalRefs),
|
|
55236
|
+
weight: 2,
|
|
55237
|
+
recommendations: unresolved.length > 0 ? [`${unresolved.length} unresolved scope refs: ${unresolved.join(", ")}`] : []
|
|
55238
|
+
};
|
|
55239
|
+
}
|
|
55240
|
+
function score(dsl) {
|
|
55241
|
+
const dimensions = [
|
|
55242
|
+
artifactValidationCoverage(dsl),
|
|
55243
|
+
taskValidationCoverage(dsl),
|
|
55244
|
+
guardrailPolicyCoverage(dsl),
|
|
55245
|
+
workflowValidationIntegration(dsl),
|
|
55246
|
+
schemaCompleteness(dsl),
|
|
55247
|
+
crossReferenceBidirectionality(dsl),
|
|
55248
|
+
guardrailScopeResolution(dsl),
|
|
55249
|
+
entityGuardrailCoverage(dsl)
|
|
55250
|
+
];
|
|
55251
|
+
const totalWeight = dimensions.reduce((s2, d2) => s2 + d2.weight, 0);
|
|
55252
|
+
const weightedSum = dimensions.reduce(
|
|
55253
|
+
(s2, d2) => s2 + d2.percent * d2.weight,
|
|
55254
|
+
0
|
|
55255
|
+
);
|
|
55256
|
+
const overall = totalWeight === 0 ? 100 : Math.round(weightedSum / totalWeight);
|
|
55257
|
+
return { overall, dimensions };
|
|
54601
55258
|
}
|
|
54602
|
-
|
|
54603
|
-
// src/cli/commands/check.ts
|
|
54604
|
-
var checkCommand = new Command5("check").description("Run full pipeline: resolve \u2192 validate \u2192 lint \u2192 render --check").option("-c, --config <path>", "Path to agent-contracts.config.yaml").option("--team <id>", "Limit to one team (multi-team config only)").option("--format <format>", "Output format (text|json)", "text").option("--quiet", "Suppress output on success", false).option("--strict", "Treat warnings as errors", false).action(
|
|
54605
|
-
async (opts) => {
|
|
54606
|
-
let hasErrors = false;
|
|
54607
|
-
try {
|
|
54608
|
-
const config = await loadConfig(opts.config);
|
|
54609
|
-
if (!config) {
|
|
54610
|
-
process.stderr.write(
|
|
54611
|
-
"Error: agent-contracts.config.yaml not found. Use --config to specify path.\n"
|
|
54612
|
-
);
|
|
54613
|
-
process.exit(1);
|
|
54614
|
-
}
|
|
54615
|
-
if (isMultiTeamConfig(config)) {
|
|
54616
|
-
const teamEntries = getTeamEntries(config, opts.team);
|
|
54617
|
-
for (const [teamId, teamConfig] of teamEntries) {
|
|
54618
|
-
if (!opts.quiet) process.stderr.write(`
|
|
54619
|
-
--- Team: ${teamId} ---
|
|
54620
|
-
`);
|
|
54621
|
-
const resolved2 = await resolve4(teamConfig.dsl);
|
|
54622
|
-
const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
|
|
54623
|
-
const schemaResult2 = validateSchema(data2);
|
|
54624
|
-
const schemaWarnings2 = schemaResult2.diagnostics.filter(
|
|
54625
|
-
(d2) => d2.severity === "warning"
|
|
54626
|
-
);
|
|
54627
|
-
if (!schemaResult2.success) {
|
|
54628
|
-
const output = formatDiagnostics(schemaResult2.diagnostics, {
|
|
54629
|
-
format: opts.format,
|
|
54630
|
-
quiet: opts.quiet
|
|
54631
|
-
});
|
|
54632
|
-
if (output) process.stderr.write(output + "\n");
|
|
54633
|
-
hasErrors = true;
|
|
54634
|
-
continue;
|
|
54635
|
-
}
|
|
54636
|
-
const refDiags2 = checkReferences(schemaResult2.data);
|
|
54637
|
-
const handoffDiags2 = validateHandoffSchemas(schemaResult2.data);
|
|
54638
|
-
const allRefDiags2 = [...refDiags2, ...handoffDiags2, ...schemaWarnings2];
|
|
54639
|
-
if (allRefDiags2.length > 0) {
|
|
54640
|
-
const output = formatDiagnostics(allRefDiags2, {
|
|
54641
|
-
format: opts.format,
|
|
54642
|
-
quiet: opts.quiet
|
|
54643
|
-
});
|
|
54644
|
-
if (output) process.stderr.write(output + "\n");
|
|
54645
|
-
hasErrors = true;
|
|
54646
|
-
}
|
|
54647
|
-
const tsLintDiags2 = lint(schemaResult2.data);
|
|
54648
|
-
const spectralDiags2 = await spectralLint(
|
|
54649
|
-
schemaResult2.data
|
|
54650
|
-
);
|
|
54651
|
-
const lintDiags2 = [...tsLintDiags2, ...spectralDiags2];
|
|
54652
|
-
if (lintDiags2.length > 0) {
|
|
54653
|
-
const output = formatDiagnostics(lintDiags2, {
|
|
54654
|
-
format: opts.format,
|
|
54655
|
-
quiet: opts.quiet
|
|
54656
|
-
});
|
|
54657
|
-
if (output) process.stderr.write(output + "\n");
|
|
54658
|
-
if (lintDiags2.some((d2) => d2.severity === "error")) {
|
|
54659
|
-
hasErrors = true;
|
|
54660
|
-
}
|
|
54661
|
-
if (opts.strict && lintDiags2.some((d2) => d2.severity === "warning")) {
|
|
54662
|
-
hasErrors = true;
|
|
54663
|
-
}
|
|
54664
|
-
}
|
|
54665
|
-
let renderOptions2;
|
|
54666
|
-
if (teamConfig.bindings.length > 0) {
|
|
54667
|
-
const loadedBindings = await loadBindings(teamConfig.bindings);
|
|
54668
|
-
renderOptions2 = {
|
|
54669
|
-
loadedBindings,
|
|
54670
|
-
activeGuardrailPolicy: teamConfig.activeGuardrailPolicy
|
|
54671
|
-
};
|
|
54672
|
-
}
|
|
54673
|
-
const drift2 = await checkDriftFromConfig(
|
|
54674
|
-
schemaResult2.data,
|
|
54675
|
-
config.renders,
|
|
54676
|
-
renderOptions2
|
|
54677
|
-
);
|
|
54678
|
-
if (drift2.hasDrift) {
|
|
54679
|
-
process.stderr.write(`Drift detected for team ${teamId} in:
|
|
54680
|
-
`);
|
|
54681
|
-
for (const f2 of drift2.diffs) {
|
|
54682
|
-
process.stderr.write(` ${f2}
|
|
54683
|
-
`);
|
|
54684
|
-
}
|
|
54685
|
-
hasErrors = true;
|
|
54686
|
-
}
|
|
54687
|
-
}
|
|
54688
|
-
if (!hasErrors) {
|
|
54689
|
-
for (const [teamId, teamConfig] of teamEntries) {
|
|
54690
|
-
const resolved2 = await resolve4(teamConfig.dsl);
|
|
54691
|
-
const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
|
|
54692
|
-
const schemaResult2 = validateSchema(data2);
|
|
54693
|
-
if (!schemaResult2.success || !schemaResult2.data) continue;
|
|
54694
|
-
const dsl = schemaResult2.data;
|
|
54695
|
-
const imports = dsl.imports;
|
|
54696
|
-
if (!imports) continue;
|
|
54697
|
-
for (const [importName, importDef] of Object.entries(imports)) {
|
|
54698
|
-
const interfacePathRel = importDef?.interface;
|
|
54699
|
-
if (typeof interfacePathRel !== "string") continue;
|
|
54700
|
-
const interfacePath = pathResolve(
|
|
54701
|
-
dirname6(teamConfig.dsl),
|
|
54702
|
-
interfacePathRel
|
|
54703
|
-
);
|
|
54704
|
-
try {
|
|
54705
|
-
await access2(interfacePath);
|
|
54706
|
-
} catch {
|
|
54707
|
-
process.stderr.write(
|
|
54708
|
-
`Cross-team error: Team "${teamId}" imports "${importName}" but interface file not found: ${interfacePath}
|
|
54709
|
-
`
|
|
54710
|
-
);
|
|
54711
|
-
hasErrors = true;
|
|
54712
|
-
}
|
|
54713
|
-
}
|
|
54714
|
-
}
|
|
54715
|
-
}
|
|
54716
|
-
if (hasErrors) process.exit(1);
|
|
54717
|
-
if (!opts.quiet) process.stdout.write("All checks passed.\n");
|
|
54718
|
-
return;
|
|
54719
|
-
}
|
|
54720
|
-
const resolved = await resolve4(config.dsl);
|
|
54721
|
-
const data = config.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
54722
|
-
const schemaResult = validateSchema(data);
|
|
54723
|
-
const schemaWarnings = schemaResult.diagnostics.filter(
|
|
54724
|
-
(d2) => d2.severity === "warning"
|
|
54725
|
-
);
|
|
54726
|
-
if (!schemaResult.success) {
|
|
54727
|
-
const output = formatDiagnostics(schemaResult.diagnostics, {
|
|
54728
|
-
format: opts.format,
|
|
54729
|
-
quiet: opts.quiet
|
|
54730
|
-
});
|
|
54731
|
-
if (output) process.stderr.write(output + "\n");
|
|
54732
|
-
process.exit(1);
|
|
54733
|
-
}
|
|
54734
|
-
const refDiags = checkReferences(schemaResult.data);
|
|
54735
|
-
const handoffDiags = validateHandoffSchemas(schemaResult.data);
|
|
54736
|
-
const allRefDiags = [...refDiags, ...handoffDiags, ...schemaWarnings];
|
|
54737
|
-
if (allRefDiags.length > 0) {
|
|
54738
|
-
const output = formatDiagnostics(allRefDiags, {
|
|
54739
|
-
format: opts.format,
|
|
54740
|
-
quiet: opts.quiet
|
|
54741
|
-
});
|
|
54742
|
-
if (output) process.stderr.write(output + "\n");
|
|
54743
|
-
hasErrors = true;
|
|
54744
|
-
}
|
|
54745
|
-
const tsLintDiags = lint(schemaResult.data);
|
|
54746
|
-
const spectralDiags = await spectralLint(schemaResult.data);
|
|
54747
|
-
const lintDiags = [...tsLintDiags, ...spectralDiags];
|
|
54748
|
-
if (lintDiags.length > 0) {
|
|
54749
|
-
const output = formatDiagnostics(lintDiags, {
|
|
54750
|
-
format: opts.format,
|
|
54751
|
-
quiet: opts.quiet
|
|
54752
|
-
});
|
|
54753
|
-
if (output) process.stderr.write(output + "\n");
|
|
54754
|
-
if (lintDiags.some((d2) => d2.severity === "error")) {
|
|
54755
|
-
hasErrors = true;
|
|
54756
|
-
}
|
|
54757
|
-
if (opts.strict && lintDiags.some((d2) => d2.severity === "warning")) {
|
|
54758
|
-
hasErrors = true;
|
|
54759
|
-
}
|
|
54760
|
-
}
|
|
54761
|
-
let renderOptions;
|
|
54762
|
-
if (config.bindings.length > 0) {
|
|
54763
|
-
const loadedBindings = await loadBindings(config.bindings);
|
|
54764
|
-
renderOptions = {
|
|
54765
|
-
loadedBindings,
|
|
54766
|
-
activeGuardrailPolicy: config.activeGuardrailPolicy
|
|
54767
|
-
};
|
|
54768
|
-
}
|
|
54769
|
-
const drift = await checkDriftFromConfig(
|
|
54770
|
-
schemaResult.data,
|
|
54771
|
-
config.renders,
|
|
54772
|
-
renderOptions
|
|
54773
|
-
);
|
|
54774
|
-
if (drift.hasDrift) {
|
|
54775
|
-
process.stderr.write("Drift detected in:\n");
|
|
54776
|
-
for (const f2 of drift.diffs) {
|
|
54777
|
-
process.stderr.write(` ${f2}
|
|
54778
|
-
`);
|
|
54779
|
-
}
|
|
54780
|
-
hasErrors = true;
|
|
54781
|
-
}
|
|
54782
|
-
if (schemaResult.data.team_interface) {
|
|
54783
|
-
const interfacePath = join3(config.configDir, "team-interface.yaml");
|
|
54784
|
-
if (existsSync(interfacePath)) {
|
|
54785
|
-
const result = generateInterface({
|
|
54786
|
-
dsl: schemaResult.data,
|
|
54787
|
-
dryRun: true,
|
|
54788
|
-
format: "yaml"
|
|
54789
|
-
});
|
|
54790
|
-
const existing = readFileSync(interfacePath, "utf8");
|
|
54791
|
-
const normalize = (raw) => {
|
|
54792
|
-
try {
|
|
54793
|
-
const parsed = parseYaml4(raw);
|
|
54794
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
54795
|
-
const { generated_at: _t, ...rest } = parsed;
|
|
54796
|
-
return `${stringify3(rest, { sortMapEntries: true })}
|
|
54797
|
-
`;
|
|
54798
|
-
}
|
|
54799
|
-
} catch {
|
|
54800
|
-
}
|
|
54801
|
-
return raw.trim();
|
|
54802
|
-
};
|
|
54803
|
-
if (normalize(existing) !== normalize(result.content)) {
|
|
54804
|
-
process.stderr.write("Drift detected in team-interface.yaml\n");
|
|
54805
|
-
hasErrors = true;
|
|
54806
|
-
}
|
|
54807
|
-
}
|
|
54808
|
-
}
|
|
54809
|
-
if (hasErrors) {
|
|
54810
|
-
process.exit(1);
|
|
54811
|
-
}
|
|
54812
|
-
if (!opts.quiet) {
|
|
54813
|
-
process.stdout.write("All checks passed.\n");
|
|
54814
|
-
}
|
|
54815
|
-
} catch (err) {
|
|
54816
|
-
if (err instanceof ConfigLoadError) {
|
|
54817
|
-
process.stderr.write(`Config error: ${err.message}
|
|
54818
|
-
`);
|
|
54819
|
-
process.exit(1);
|
|
54820
|
-
}
|
|
54821
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
54822
|
-
process.stderr.write(`Error: ${msg}
|
|
54823
|
-
`);
|
|
54824
|
-
process.exit(1);
|
|
54825
|
-
}
|
|
54826
|
-
}
|
|
54827
|
-
);
|
|
54828
|
-
|
|
54829
|
-
// src/cli/commands/generate-guardrails.ts
|
|
54830
|
-
import { Command as Command6 } from "commander";
|
|
54831
55259
|
|
|
54832
55260
|
// src/guardrail-generator/generator.ts
|
|
54833
55261
|
import { readFile as readFile5, writeFile as writeFile2, mkdir as mkdir2, chmod, unlink as unlink2, copyFile } from "fs/promises";
|
|
54834
|
-
import { resolve as resolve6, dirname as
|
|
55262
|
+
import { resolve as resolve6, dirname as dirname6 } from "path";
|
|
54835
55263
|
import Handlebars2 from "handlebars";
|
|
54836
55264
|
import YAML from "yaml";
|
|
54837
55265
|
|
|
@@ -55058,7 +55486,7 @@ async function generateGuardrails(options) {
|
|
|
55058
55486
|
const sourcePath = resolve6(config.configDir, outputDef.source);
|
|
55059
55487
|
if (!dryRun) {
|
|
55060
55488
|
try {
|
|
55061
|
-
await mkdir2(
|
|
55489
|
+
await mkdir2(dirname6(targetPath), { recursive: true });
|
|
55062
55490
|
await copyFile(sourcePath, targetPath);
|
|
55063
55491
|
if (outputDef.executable) {
|
|
55064
55492
|
await chmod(targetPath, 493);
|
|
@@ -55142,7 +55570,7 @@ async function generateGuardrails(options) {
|
|
|
55142
55570
|
}
|
|
55143
55571
|
const output = isPatch && !dryRun ? await applyPatch(groupTarget, rendered, outputDef) : rendered;
|
|
55144
55572
|
if (!dryRun) {
|
|
55145
|
-
await mkdir2(
|
|
55573
|
+
await mkdir2(dirname6(groupTarget), { recursive: true });
|
|
55146
55574
|
await writeFile2(groupTarget, output, "utf8");
|
|
55147
55575
|
if (outputDef.executable) {
|
|
55148
55576
|
await chmod(groupTarget, 493);
|
|
@@ -55163,7 +55591,7 @@ async function generateGuardrails(options) {
|
|
|
55163
55591
|
} else {
|
|
55164
55592
|
const output = isPatch && !dryRun ? await applyPatch(targetPath, rendered, outputDef) : rendered;
|
|
55165
55593
|
if (!dryRun) {
|
|
55166
|
-
await mkdir2(
|
|
55594
|
+
await mkdir2(dirname6(targetPath), { recursive: true });
|
|
55167
55595
|
await writeFile2(targetPath, output, "utf8");
|
|
55168
55596
|
if (outputDef.executable) {
|
|
55169
55597
|
await chmod(targetPath, 493);
|
|
@@ -55216,7 +55644,7 @@ async function generateGuardrails(options) {
|
|
|
55216
55644
|
continue;
|
|
55217
55645
|
}
|
|
55218
55646
|
if (!dryRun) {
|
|
55219
|
-
await mkdir2(
|
|
55647
|
+
await mkdir2(dirname6(outputPath), { recursive: true });
|
|
55220
55648
|
await writeFile2(outputPath, rendered, "utf8");
|
|
55221
55649
|
if (renderTarget.executable) {
|
|
55222
55650
|
await chmod(outputPath, 493);
|
|
@@ -55246,7 +55674,7 @@ async function generateGuardrails(options) {
|
|
|
55246
55674
|
continue;
|
|
55247
55675
|
}
|
|
55248
55676
|
if (!dryRun) {
|
|
55249
|
-
await mkdir2(
|
|
55677
|
+
await mkdir2(dirname6(outputPath), { recursive: true });
|
|
55250
55678
|
await writeFile2(outputPath, rendered, "utf8");
|
|
55251
55679
|
if (renderTarget.executable) {
|
|
55252
55680
|
await chmod(outputPath, 493);
|
|
@@ -55266,659 +55694,81 @@ function resolveBindingRenderOutputPath(output, paths) {
|
|
|
55266
55694
|
});
|
|
55267
55695
|
}
|
|
55268
55696
|
|
|
55269
|
-
// src/
|
|
55270
|
-
import {
|
|
55271
|
-
|
|
55272
|
-
|
|
55273
|
-
|
|
55274
|
-
|
|
55275
|
-
|
|
55276
|
-
|
|
55277
|
-
|
|
55278
|
-
const result = generateInterface({
|
|
55279
|
-
dsl: opts.dsl,
|
|
55280
|
-
output: outputPath,
|
|
55281
|
-
dryRun: opts.dryRun,
|
|
55282
|
-
format: opts.format
|
|
55283
|
-
});
|
|
55284
|
-
if (opts.dryRun) {
|
|
55285
|
-
process.stdout.write(result.content);
|
|
55286
|
-
return;
|
|
55287
|
-
}
|
|
55288
|
-
writeFileSync(result.outputPath, result.content, "utf8");
|
|
55289
|
-
if (!opts.quiet) {
|
|
55290
|
-
process.stdout.write(`Wrote ${result.outputPath}
|
|
55291
|
-
`);
|
|
55292
|
-
}
|
|
55293
|
-
}
|
|
55294
|
-
|
|
55295
|
-
// src/cli/commands/generate-guardrails.ts
|
|
55296
|
-
function resolvedConfigForTeam(workspace, teamConfig) {
|
|
55297
|
-
return {
|
|
55298
|
-
dsl: "",
|
|
55299
|
-
vars: teamConfig.vars,
|
|
55300
|
-
renders: workspace.renders,
|
|
55301
|
-
configDir: workspace.configDir,
|
|
55302
|
-
bindings: teamConfig.bindings,
|
|
55303
|
-
activeGuardrailPolicy: teamConfig.activeGuardrailPolicy,
|
|
55304
|
-
paths: teamConfig.paths
|
|
55305
|
-
};
|
|
55306
|
-
}
|
|
55307
|
-
var generateGuardrailsCommand = new Command6("generate").description("Generate guardrail runtime artifacts from DSL, policies, and bindings").argument("[type]", "Type of artifacts to generate (guardrails|interface)", "guardrails").option("-c, --config <path>", "Path to agent-contracts.config.yaml").option("--team <id>", "Limit to one team (multi-team config only)").option("--binding <name...>", "Filter to specific software binding(s)").option(
|
|
55308
|
-
"-o, --output <path>",
|
|
55309
|
-
"Output path for generated team interface (interface type only)"
|
|
55310
|
-
).option(
|
|
55311
|
-
"--format <format>",
|
|
55312
|
-
"Output format for team interface: yaml or json",
|
|
55313
|
-
"yaml"
|
|
55314
|
-
).option("--dry-run", "Print what would be generated without writing files", false).option("--quiet", "Suppress output on success", false).action(
|
|
55315
|
-
async (type, opts) => {
|
|
55316
|
-
if (type !== "guardrails" && type !== "interface") {
|
|
55317
|
-
process.stderr.write(`Unknown generate type: ${type}
|
|
55318
|
-
`);
|
|
55319
|
-
process.exit(1);
|
|
55320
|
-
}
|
|
55321
|
-
if (type === "interface" && opts.format !== "yaml" && opts.format !== "json") {
|
|
55322
|
-
process.stderr.write(`Invalid --format: expected yaml or json, got ${opts.format}
|
|
55323
|
-
`);
|
|
55324
|
-
process.exit(1);
|
|
55325
|
-
}
|
|
55326
|
-
try {
|
|
55327
|
-
const config = await loadConfig(opts.config);
|
|
55328
|
-
if (!config) {
|
|
55329
|
-
process.stderr.write(
|
|
55330
|
-
"Error: agent-contracts.config.yaml not found. Use --config to specify path.\n"
|
|
55331
|
-
);
|
|
55332
|
-
process.exit(1);
|
|
55333
|
-
}
|
|
55334
|
-
if (isMultiTeamConfig(config)) {
|
|
55335
|
-
const teamEntries = getTeamEntries(config, opts.team);
|
|
55336
|
-
let exitWithError = false;
|
|
55337
|
-
for (const [teamId, teamConfig] of teamEntries) {
|
|
55338
|
-
if (!opts.quiet) process.stdout.write(`
|
|
55339
|
-
--- Team: ${teamId} ---
|
|
55340
|
-
`);
|
|
55341
|
-
const resolved2 = await resolve4(teamConfig.dsl);
|
|
55342
|
-
const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
|
|
55343
|
-
const schemaResult2 = validateSchema(data2);
|
|
55344
|
-
if (!schemaResult2.success) {
|
|
55345
|
-
process.stderr.write(
|
|
55346
|
-
`Schema validation failed for team ${teamId}. Run 'agent-contracts validate' for details.
|
|
55347
|
-
`
|
|
55348
|
-
);
|
|
55349
|
-
exitWithError = true;
|
|
55350
|
-
continue;
|
|
55351
|
-
}
|
|
55352
|
-
if (type === "interface") {
|
|
55353
|
-
runGenerateInterfaceCli({
|
|
55354
|
-
dsl: schemaResult2.data,
|
|
55355
|
-
output: teamConfig.interfaceOutput ?? opts.output,
|
|
55356
|
-
dryRun: opts.dryRun,
|
|
55357
|
-
format: opts.format,
|
|
55358
|
-
quiet: opts.quiet
|
|
55359
|
-
});
|
|
55360
|
-
continue;
|
|
55361
|
-
}
|
|
55362
|
-
const loadedBindings2 = await loadBindings(teamConfig.bindings);
|
|
55363
|
-
const result2 = await generateGuardrails({
|
|
55364
|
-
dsl: schemaResult2.data,
|
|
55365
|
-
config: resolvedConfigForTeam(config, teamConfig),
|
|
55366
|
-
loadedBindings: loadedBindings2,
|
|
55367
|
-
filterBindings: opts.binding,
|
|
55368
|
-
dryRun: opts.dryRun
|
|
55369
|
-
});
|
|
55370
|
-
const errors2 = result2.diagnostics.filter((d2) => d2.severity === "error");
|
|
55371
|
-
const warnings2 = result2.diagnostics.filter((d2) => d2.severity === "warning");
|
|
55372
|
-
const infos2 = result2.diagnostics.filter((d2) => d2.severity === "info");
|
|
55373
|
-
if (errors2.length > 0) {
|
|
55374
|
-
process.stderr.write(`Errors (team ${teamId}):
|
|
55375
|
-
`);
|
|
55376
|
-
for (const d2 of errors2) {
|
|
55377
|
-
process.stderr.write(` error [${d2.path}] ${d2.message}
|
|
55378
|
-
`);
|
|
55379
|
-
}
|
|
55380
|
-
exitWithError = true;
|
|
55381
|
-
}
|
|
55382
|
-
if (warnings2.length > 0 && !opts.quiet) {
|
|
55383
|
-
process.stderr.write(`Warnings (team ${teamId}):
|
|
55384
|
-
`);
|
|
55385
|
-
for (const d2 of warnings2) {
|
|
55386
|
-
process.stderr.write(` warning [${d2.path}] ${d2.message}
|
|
55387
|
-
`);
|
|
55388
|
-
}
|
|
55389
|
-
}
|
|
55390
|
-
if (infos2.length > 0 && !opts.quiet) {
|
|
55391
|
-
for (const d2 of infos2) {
|
|
55392
|
-
process.stderr.write(` info [${d2.path}] ${d2.message}
|
|
55393
|
-
`);
|
|
55394
|
-
}
|
|
55395
|
-
}
|
|
55396
|
-
if (!opts.quiet) {
|
|
55397
|
-
const action = opts.dryRun ? "Would generate" : "Generated";
|
|
55398
|
-
process.stdout.write(
|
|
55399
|
-
`${action} ${result2.outputFiles.length} file(s):
|
|
55400
|
-
`
|
|
55401
|
-
);
|
|
55402
|
-
for (const f2 of result2.outputFiles) {
|
|
55403
|
-
process.stdout.write(` ${f2}
|
|
55404
|
-
`);
|
|
55405
|
-
}
|
|
55406
|
-
}
|
|
55407
|
-
}
|
|
55408
|
-
if (exitWithError) process.exit(1);
|
|
55409
|
-
return;
|
|
55410
|
-
}
|
|
55411
|
-
const resolved = await resolve4(config.dsl);
|
|
55412
|
-
const data = config.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
55413
|
-
const schemaResult = validateSchema(data);
|
|
55414
|
-
if (!schemaResult.success) {
|
|
55415
|
-
process.stderr.write(
|
|
55416
|
-
"Schema validation failed. Run 'agent-contracts validate' for details.\n"
|
|
55417
|
-
);
|
|
55418
|
-
process.exit(1);
|
|
55419
|
-
}
|
|
55420
|
-
if (type === "interface") {
|
|
55421
|
-
runGenerateInterfaceCli({
|
|
55422
|
-
dsl: schemaResult.data,
|
|
55423
|
-
output: opts.output,
|
|
55424
|
-
dryRun: opts.dryRun,
|
|
55425
|
-
format: opts.format,
|
|
55426
|
-
quiet: opts.quiet
|
|
55427
|
-
});
|
|
55428
|
-
return;
|
|
55429
|
-
}
|
|
55430
|
-
const loadedBindings = await loadBindings(config.bindings);
|
|
55431
|
-
const result = await generateGuardrails({
|
|
55432
|
-
dsl: schemaResult.data,
|
|
55433
|
-
config,
|
|
55434
|
-
loadedBindings,
|
|
55435
|
-
filterBindings: opts.binding,
|
|
55436
|
-
dryRun: opts.dryRun
|
|
55437
|
-
});
|
|
55438
|
-
const errors = result.diagnostics.filter((d2) => d2.severity === "error");
|
|
55439
|
-
const warnings = result.diagnostics.filter((d2) => d2.severity === "warning");
|
|
55440
|
-
const infos = result.diagnostics.filter((d2) => d2.severity === "info");
|
|
55441
|
-
if (errors.length > 0) {
|
|
55442
|
-
process.stderr.write("Errors:\n");
|
|
55443
|
-
for (const d2 of errors) {
|
|
55444
|
-
process.stderr.write(` error [${d2.path}] ${d2.message}
|
|
55445
|
-
`);
|
|
55446
|
-
}
|
|
55447
|
-
}
|
|
55448
|
-
if (warnings.length > 0 && !opts.quiet) {
|
|
55449
|
-
process.stderr.write("Warnings:\n");
|
|
55450
|
-
for (const d2 of warnings) {
|
|
55451
|
-
process.stderr.write(` warning [${d2.path}] ${d2.message}
|
|
55452
|
-
`);
|
|
55453
|
-
}
|
|
55454
|
-
}
|
|
55455
|
-
if (infos.length > 0 && !opts.quiet) {
|
|
55456
|
-
for (const d2 of infos) {
|
|
55457
|
-
process.stderr.write(` info [${d2.path}] ${d2.message}
|
|
55458
|
-
`);
|
|
55459
|
-
}
|
|
55460
|
-
}
|
|
55461
|
-
if (errors.length > 0) {
|
|
55462
|
-
process.exit(1);
|
|
55463
|
-
}
|
|
55464
|
-
if (!opts.quiet) {
|
|
55465
|
-
const action = opts.dryRun ? "Would generate" : "Generated";
|
|
55466
|
-
process.stdout.write(
|
|
55467
|
-
`${action} ${result.outputFiles.length} file(s):
|
|
55468
|
-
`
|
|
55469
|
-
);
|
|
55470
|
-
for (const f2 of result.outputFiles) {
|
|
55471
|
-
process.stdout.write(` ${f2}
|
|
55472
|
-
`);
|
|
55473
|
-
}
|
|
55474
|
-
}
|
|
55475
|
-
} catch (err) {
|
|
55476
|
-
if (err instanceof ConfigLoadError) {
|
|
55477
|
-
process.stderr.write(`Config error: ${err.message}
|
|
55478
|
-
`);
|
|
55479
|
-
process.exit(1);
|
|
55480
|
-
}
|
|
55481
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
55482
|
-
process.stderr.write(`Error: ${msg}
|
|
55483
|
-
`);
|
|
55484
|
-
process.exit(1);
|
|
55485
|
-
}
|
|
55486
|
-
}
|
|
55487
|
-
);
|
|
55488
|
-
|
|
55489
|
-
// src/cli/commands/score.ts
|
|
55490
|
-
import { Command as Command7 } from "commander";
|
|
55491
|
-
|
|
55492
|
-
// src/scorer/scorer.ts
|
|
55493
|
-
function pct(n3, d2) {
|
|
55494
|
-
return d2 === 0 ? 100 : Math.round(n3 / d2 * 100);
|
|
55495
|
-
}
|
|
55496
|
-
function artifactValidationCoverage(dsl) {
|
|
55497
|
-
const entries = Object.entries(dsl.artifacts);
|
|
55498
|
-
const total = entries.length;
|
|
55499
|
-
const covered = entries.filter(
|
|
55500
|
-
([, a3]) => a3.required_validations.length > 0
|
|
55501
|
-
).length;
|
|
55502
|
-
const missing = entries.filter(([, a3]) => a3.required_validations.length === 0).map(([id]) => id);
|
|
55503
|
-
return {
|
|
55504
|
-
id: "artifact-validation-coverage",
|
|
55505
|
-
label: "Artifact validation coverage",
|
|
55506
|
-
score: covered,
|
|
55507
|
-
total,
|
|
55508
|
-
percent: pct(covered, total),
|
|
55509
|
-
weight: 3,
|
|
55510
|
-
recommendations: missing.length > 0 ? [`${missing.length} artifacts missing required_validations: ${missing.join(", ")}`] : []
|
|
55511
|
-
};
|
|
55512
|
-
}
|
|
55513
|
-
function taskValidationCoverage(dsl) {
|
|
55514
|
-
const entries = Object.entries(dsl.tasks);
|
|
55515
|
-
const total = entries.length;
|
|
55516
|
-
const covered = entries.filter(([, t3]) => t3.validations.length > 0).length;
|
|
55517
|
-
const missing = entries.filter(([, t3]) => t3.validations.length === 0).map(([id]) => id);
|
|
55518
|
-
return {
|
|
55519
|
-
id: "task-validation-coverage",
|
|
55520
|
-
label: "Task validation coverage",
|
|
55521
|
-
score: covered,
|
|
55522
|
-
total,
|
|
55523
|
-
percent: pct(covered, total),
|
|
55524
|
-
weight: 3,
|
|
55525
|
-
recommendations: missing.length > 0 ? [`${missing.length} tasks missing validations: ${missing.join(", ")}`] : []
|
|
55526
|
-
};
|
|
55527
|
-
}
|
|
55528
|
-
function guardrailPolicyCoverage(dsl) {
|
|
55529
|
-
const guardrailIds = Object.keys(dsl.guardrails);
|
|
55530
|
-
const total = guardrailIds.length;
|
|
55531
|
-
const referenced = /* @__PURE__ */ new Set();
|
|
55532
|
-
for (const policy of Object.values(dsl.guardrail_policies)) {
|
|
55533
|
-
for (const rule of policy.rules) {
|
|
55534
|
-
referenced.add(rule.guardrail);
|
|
55535
|
-
}
|
|
55536
|
-
}
|
|
55537
|
-
const covered = guardrailIds.filter((id) => referenced.has(id)).length;
|
|
55538
|
-
const missing = guardrailIds.filter((id) => !referenced.has(id));
|
|
55539
|
-
return {
|
|
55540
|
-
id: "guardrail-policy-coverage",
|
|
55541
|
-
label: "Guardrail policy coverage",
|
|
55542
|
-
score: covered,
|
|
55543
|
-
total,
|
|
55544
|
-
percent: pct(covered, total),
|
|
55545
|
-
weight: 2,
|
|
55546
|
-
recommendations: missing.length > 0 ? [`${missing.length} guardrails not in any policy: ${missing.join(", ")}`] : []
|
|
55547
|
-
};
|
|
55548
|
-
}
|
|
55549
|
-
function workflowValidationIntegration(dsl) {
|
|
55550
|
-
const blockingValidations = Object.entries(dsl.validations).filter(
|
|
55551
|
-
([, v2]) => v2.blocking
|
|
55552
|
-
);
|
|
55553
|
-
const total = blockingValidations.length;
|
|
55554
|
-
const referenced = /* @__PURE__ */ new Set();
|
|
55555
|
-
for (const wf of Object.values(dsl.workflow)) {
|
|
55556
|
-
for (const step of wf.steps) {
|
|
55557
|
-
if (step.type === "validation") {
|
|
55558
|
-
referenced.add(step.validation);
|
|
55559
|
-
}
|
|
55560
|
-
}
|
|
55561
|
-
}
|
|
55562
|
-
for (const task of Object.values(dsl.tasks)) {
|
|
55563
|
-
for (const valId of task.validations) {
|
|
55564
|
-
referenced.add(valId);
|
|
55565
|
-
}
|
|
55566
|
-
}
|
|
55567
|
-
const covered = blockingValidations.filter(
|
|
55568
|
-
([id]) => referenced.has(id)
|
|
55569
|
-
).length;
|
|
55570
|
-
const missing = blockingValidations.filter(([id]) => !referenced.has(id)).map(([id]) => id);
|
|
55571
|
-
return {
|
|
55572
|
-
id: "workflow-validation-integration",
|
|
55573
|
-
label: "Workflow validation integration",
|
|
55574
|
-
score: covered,
|
|
55575
|
-
total,
|
|
55576
|
-
percent: pct(covered, total),
|
|
55577
|
-
weight: 3,
|
|
55578
|
-
recommendations: missing.length > 0 ? [`${missing.length} blocking validations not wired: ${missing.join(", ")}`] : []
|
|
55697
|
+
// src/interface-generator/generator.ts
|
|
55698
|
+
import { stringify } from "yaml";
|
|
55699
|
+
function buildInterfaceDocument(dsl, generatedAt) {
|
|
55700
|
+
const ti = dsl.team_interface;
|
|
55701
|
+
const doc = {
|
|
55702
|
+
team_id: dsl.system.id,
|
|
55703
|
+
team_name: dsl.system.name,
|
|
55704
|
+
version: ti.version,
|
|
55705
|
+
generated_at: generatedAt
|
|
55579
55706
|
};
|
|
55580
|
-
|
|
55581
|
-
|
|
55582
|
-
agents: {
|
|
55583
|
-
section: "agents",
|
|
55584
|
-
fields: ["responsibilities", "constraints", "rules"]
|
|
55585
|
-
},
|
|
55586
|
-
tasks: {
|
|
55587
|
-
section: "tasks",
|
|
55588
|
-
fields: ["description", "responsibilities", "execution_steps", "completion_criteria"]
|
|
55589
|
-
},
|
|
55590
|
-
artifacts: {
|
|
55591
|
-
section: "artifacts",
|
|
55592
|
-
fields: ["description", "visibility"]
|
|
55593
|
-
},
|
|
55594
|
-
tools: {
|
|
55595
|
-
section: "tools",
|
|
55596
|
-
fields: ["description", "commands"]
|
|
55597
|
-
},
|
|
55598
|
-
workflow: {
|
|
55599
|
-
section: "workflow",
|
|
55600
|
-
fields: ["description", "trigger", "entry_conditions"]
|
|
55601
|
-
},
|
|
55602
|
-
guardrails: {
|
|
55603
|
-
section: "guardrails",
|
|
55604
|
-
fields: ["rationale", "tags"]
|
|
55605
|
-
}
|
|
55606
|
-
};
|
|
55607
|
-
function hasNonEmpty(obj, field) {
|
|
55608
|
-
const val = obj[field];
|
|
55609
|
-
if (val === void 0 || val === null) return false;
|
|
55610
|
-
if (typeof val === "string") return val.length > 0;
|
|
55611
|
-
if (Array.isArray(val)) return val.length > 0;
|
|
55612
|
-
return true;
|
|
55613
|
-
}
|
|
55614
|
-
function schemaCompleteness(dsl) {
|
|
55615
|
-
let totalSlots = 0;
|
|
55616
|
-
let filledSlots = 0;
|
|
55617
|
-
const lowSections = [];
|
|
55618
|
-
for (const [sectionKey, meta] of Object.entries(OPTIONAL_ENTITY_FIELDS)) {
|
|
55619
|
-
const entities = dsl[meta.section];
|
|
55620
|
-
if (!entities) continue;
|
|
55621
|
-
let sectionTotal = 0;
|
|
55622
|
-
let sectionFilled = 0;
|
|
55623
|
-
for (const entity of Object.values(entities)) {
|
|
55624
|
-
for (const field of meta.fields) {
|
|
55625
|
-
sectionTotal++;
|
|
55626
|
-
totalSlots++;
|
|
55627
|
-
if (hasNonEmpty(entity, field)) {
|
|
55628
|
-
sectionFilled++;
|
|
55629
|
-
filledSlots++;
|
|
55630
|
-
}
|
|
55631
|
-
}
|
|
55632
|
-
}
|
|
55633
|
-
if (sectionTotal > 0 && pct(sectionFilled, sectionTotal) < 50) {
|
|
55634
|
-
lowSections.push(sectionKey);
|
|
55635
|
-
}
|
|
55707
|
+
if (ti.description !== void 0) {
|
|
55708
|
+
doc.description = ti.description;
|
|
55636
55709
|
}
|
|
55637
|
-
|
|
55638
|
-
|
|
55639
|
-
label: "Schema completeness",
|
|
55640
|
-
score: filledSlots,
|
|
55641
|
-
total: totalSlots,
|
|
55642
|
-
percent: pct(filledSlots, totalSlots),
|
|
55643
|
-
weight: 1,
|
|
55644
|
-
recommendations: lowSections.length > 0 ? [`Low optional field coverage in: ${lowSections.join(", ")}`] : []
|
|
55645
|
-
};
|
|
55646
|
-
}
|
|
55647
|
-
function crossReferenceBidirectionality(dsl) {
|
|
55648
|
-
let totalChecks = 0;
|
|
55649
|
-
let passedChecks = 0;
|
|
55650
|
-
const issues = [];
|
|
55651
|
-
for (const [agentId, agent] of Object.entries(dsl.agents)) {
|
|
55652
|
-
for (const toolId of agent.can_execute_tools) {
|
|
55653
|
-
totalChecks++;
|
|
55654
|
-
const tool = dsl.tools[toolId];
|
|
55655
|
-
if (tool && tool.invokable_by.includes(agentId)) {
|
|
55656
|
-
passedChecks++;
|
|
55657
|
-
} else {
|
|
55658
|
-
issues.push(`agent ${agentId} \u2192 tool ${toolId}`);
|
|
55659
|
-
}
|
|
55660
|
-
}
|
|
55661
|
-
for (const artId of agent.can_write_artifacts) {
|
|
55662
|
-
totalChecks++;
|
|
55663
|
-
const art = dsl.artifacts[artId];
|
|
55664
|
-
if (art && (art.producers.includes(agentId) || art.editors.includes(agentId))) {
|
|
55665
|
-
passedChecks++;
|
|
55666
|
-
} else {
|
|
55667
|
-
issues.push(`agent ${agentId} \u2192 artifact ${artId} (write)`);
|
|
55668
|
-
}
|
|
55669
|
-
}
|
|
55670
|
-
for (const artId of agent.can_read_artifacts) {
|
|
55671
|
-
totalChecks++;
|
|
55672
|
-
const art = dsl.artifacts[artId];
|
|
55673
|
-
if (art && (art.consumers.includes(agentId) || art.producers.includes(agentId) || art.editors.includes(agentId))) {
|
|
55674
|
-
passedChecks++;
|
|
55675
|
-
} else {
|
|
55676
|
-
issues.push(`agent ${agentId} \u2192 artifact ${artId} (read)`);
|
|
55677
|
-
}
|
|
55678
|
-
}
|
|
55710
|
+
if (ti.accepts?.workflows && Object.keys(ti.accepts.workflows).length > 0) {
|
|
55711
|
+
doc.accepts = { workflows: { ...ti.accepts.workflows } };
|
|
55679
55712
|
}
|
|
55680
|
-
|
|
55681
|
-
|
|
55682
|
-
|
|
55683
|
-
|
|
55684
|
-
|
|
55685
|
-
passedChecks++;
|
|
55686
|
-
} else {
|
|
55687
|
-
issues.push(`tool ${toolId} \u2192 agent ${agentId}`);
|
|
55688
|
-
}
|
|
55713
|
+
const handoffKeys = /* @__PURE__ */ new Set();
|
|
55714
|
+
if (ti.accepts?.workflows) {
|
|
55715
|
+
for (const spec of Object.values(ti.accepts.workflows)) {
|
|
55716
|
+
handoffKeys.add(spec.input_handoff);
|
|
55717
|
+
handoffKeys.add(spec.output_handoff);
|
|
55689
55718
|
}
|
|
55690
55719
|
}
|
|
55691
|
-
|
|
55692
|
-
|
|
55693
|
-
|
|
55694
|
-
|
|
55695
|
-
|
|
55696
|
-
|
|
55697
|
-
|
|
55698
|
-
|
|
55699
|
-
|
|
55700
|
-
|
|
55701
|
-
function entityGuardrailCoverage(dsl) {
|
|
55702
|
-
const entitySections = [
|
|
55703
|
-
{ name: "agents", entities: dsl.agents },
|
|
55704
|
-
{ name: "tasks", entities: dsl.tasks },
|
|
55705
|
-
{ name: "tools", entities: dsl.tools },
|
|
55706
|
-
{ name: "artifacts", entities: dsl.artifacts }
|
|
55707
|
-
];
|
|
55708
|
-
const scopeBindings = {
|
|
55709
|
-
agents: /* @__PURE__ */ new Set(),
|
|
55710
|
-
tasks: /* @__PURE__ */ new Set(),
|
|
55711
|
-
tools: /* @__PURE__ */ new Set(),
|
|
55712
|
-
artifacts: /* @__PURE__ */ new Set()
|
|
55713
|
-
};
|
|
55714
|
-
for (const guardrail of Object.values(dsl.guardrails)) {
|
|
55715
|
-
for (const key of Object.keys(scopeBindings)) {
|
|
55716
|
-
const ids = guardrail.scope[key];
|
|
55717
|
-
if (ids) {
|
|
55718
|
-
for (const id of ids) scopeBindings[key].add(id);
|
|
55720
|
+
const handoff_types = {};
|
|
55721
|
+
for (const k2 of [...handoffKeys].sort()) {
|
|
55722
|
+
const ht = dsl.handoff_types[k2];
|
|
55723
|
+
if (ht) {
|
|
55724
|
+
const entry = {
|
|
55725
|
+
version: ht.version,
|
|
55726
|
+
schema: ht.schema
|
|
55727
|
+
};
|
|
55728
|
+
if (ht.description !== void 0) {
|
|
55729
|
+
entry.description = ht.description;
|
|
55719
55730
|
}
|
|
55731
|
+
handoff_types[k2] = entry;
|
|
55720
55732
|
}
|
|
55721
55733
|
}
|
|
55722
|
-
|
|
55723
|
-
|
|
55724
|
-
const missing = [];
|
|
55725
|
-
for (const { name, entities } of entitySections) {
|
|
55726
|
-
for (const [entityId, entity] of Object.entries(entities)) {
|
|
55727
|
-
total++;
|
|
55728
|
-
const hasEntitySide = (entity.guardrails ?? []).length > 0;
|
|
55729
|
-
const hasScopeSide = scopeBindings[name].has(entityId);
|
|
55730
|
-
if (hasEntitySide || hasScopeSide) {
|
|
55731
|
-
covered++;
|
|
55732
|
-
} else {
|
|
55733
|
-
missing.push(`${name}.${entityId}`);
|
|
55734
|
-
}
|
|
55735
|
-
}
|
|
55734
|
+
if (Object.keys(handoff_types).length > 0) {
|
|
55735
|
+
doc.handoff_types = handoff_types;
|
|
55736
55736
|
}
|
|
55737
|
-
|
|
55738
|
-
|
|
55739
|
-
|
|
55740
|
-
|
|
55741
|
-
|
|
55742
|
-
|
|
55743
|
-
|
|
55744
|
-
|
|
55745
|
-
|
|
55746
|
-
|
|
55747
|
-
|
|
55748
|
-
let totalRefs = 0;
|
|
55749
|
-
let resolvedRefs = 0;
|
|
55750
|
-
const unresolved = [];
|
|
55751
|
-
const sectionMap = {
|
|
55752
|
-
agents: dsl.agents,
|
|
55753
|
-
tasks: dsl.tasks,
|
|
55754
|
-
tools: dsl.tools,
|
|
55755
|
-
artifacts: dsl.artifacts,
|
|
55756
|
-
workflows: dsl.workflow
|
|
55757
|
-
};
|
|
55758
|
-
for (const [guardrailId, guardrail] of Object.entries(dsl.guardrails)) {
|
|
55759
|
-
const scope = guardrail.scope;
|
|
55760
|
-
for (const [scopeKey, entityIds] of Object.entries(scope)) {
|
|
55761
|
-
if (!Array.isArray(entityIds)) continue;
|
|
55762
|
-
const section = sectionMap[scopeKey];
|
|
55763
|
-
if (!section) continue;
|
|
55764
|
-
for (const entityId of entityIds) {
|
|
55765
|
-
totalRefs++;
|
|
55766
|
-
if (section[entityId]) {
|
|
55767
|
-
resolvedRefs++;
|
|
55768
|
-
} else {
|
|
55769
|
-
unresolved.push(`${guardrailId}.scope.${scopeKey}: ${entityId}`);
|
|
55737
|
+
const artifactsOut = {};
|
|
55738
|
+
if (ti.exposes?.artifacts) {
|
|
55739
|
+
for (const key of [...ti.exposes.artifacts].sort()) {
|
|
55740
|
+
const art = dsl.artifacts[key];
|
|
55741
|
+
if (art) {
|
|
55742
|
+
const entry = {
|
|
55743
|
+
type: art.type,
|
|
55744
|
+
states: art.states
|
|
55745
|
+
};
|
|
55746
|
+
if (art.description !== void 0) {
|
|
55747
|
+
entry.description = art.description;
|
|
55770
55748
|
}
|
|
55749
|
+
artifactsOut[key] = entry;
|
|
55771
55750
|
}
|
|
55772
55751
|
}
|
|
55773
55752
|
}
|
|
55774
|
-
|
|
55775
|
-
|
|
55776
|
-
label: "Guardrail scope resolution",
|
|
55777
|
-
score: resolvedRefs,
|
|
55778
|
-
total: totalRefs,
|
|
55779
|
-
percent: pct(resolvedRefs, totalRefs),
|
|
55780
|
-
weight: 2,
|
|
55781
|
-
recommendations: unresolved.length > 0 ? [`${unresolved.length} unresolved scope refs: ${unresolved.join(", ")}`] : []
|
|
55782
|
-
};
|
|
55783
|
-
}
|
|
55784
|
-
function score(dsl) {
|
|
55785
|
-
const dimensions = [
|
|
55786
|
-
artifactValidationCoverage(dsl),
|
|
55787
|
-
taskValidationCoverage(dsl),
|
|
55788
|
-
guardrailPolicyCoverage(dsl),
|
|
55789
|
-
workflowValidationIntegration(dsl),
|
|
55790
|
-
schemaCompleteness(dsl),
|
|
55791
|
-
crossReferenceBidirectionality(dsl),
|
|
55792
|
-
guardrailScopeResolution(dsl),
|
|
55793
|
-
entityGuardrailCoverage(dsl)
|
|
55794
|
-
];
|
|
55795
|
-
const totalWeight = dimensions.reduce((s2, d2) => s2 + d2.weight, 0);
|
|
55796
|
-
const weightedSum = dimensions.reduce(
|
|
55797
|
-
(s2, d2) => s2 + d2.percent * d2.weight,
|
|
55798
|
-
0
|
|
55799
|
-
);
|
|
55800
|
-
const overall = totalWeight === 0 ? 100 : Math.round(weightedSum / totalWeight);
|
|
55801
|
-
return { overall, dimensions };
|
|
55802
|
-
}
|
|
55803
|
-
|
|
55804
|
-
// src/cli/commands/score.ts
|
|
55805
|
-
var DIR_DEFAULT4 = "agent-contracts.yaml";
|
|
55806
|
-
function formatText(result) {
|
|
55807
|
-
const lines = [];
|
|
55808
|
-
lines.push(`DSL Completeness Score: ${result.overall}/100`);
|
|
55809
|
-
lines.push("");
|
|
55810
|
-
for (const d2 of result.dimensions) {
|
|
55811
|
-
const detail = d2.total > 0 ? ` (${d2.score}/${d2.total} ${d2.id.split("-")[0]})` : "";
|
|
55812
|
-
lines.push(
|
|
55813
|
-
` ${d2.label.padEnd(40)} ${String(d2.percent).padStart(3)}%${detail}`
|
|
55814
|
-
);
|
|
55753
|
+
if (Object.keys(artifactsOut).length > 0) {
|
|
55754
|
+
doc.exposes = { artifacts: artifactsOut };
|
|
55815
55755
|
}
|
|
55816
|
-
|
|
55817
|
-
|
|
55818
|
-
lines.push("");
|
|
55819
|
-
lines.push("Recommendations:");
|
|
55820
|
-
for (const rec of allRecs) {
|
|
55821
|
-
lines.push(` - ${rec}`);
|
|
55822
|
-
}
|
|
55756
|
+
if (ti.constraints !== void 0 && ti.constraints.length > 0) {
|
|
55757
|
+
doc.constraints = ti.constraints;
|
|
55823
55758
|
}
|
|
55824
|
-
return
|
|
55759
|
+
return doc;
|
|
55825
55760
|
}
|
|
55826
|
-
|
|
55827
|
-
|
|
55828
|
-
|
|
55829
|
-
const config = await loadConfig(opts.config);
|
|
55830
|
-
if (config !== null && isMultiTeamConfig(config)) {
|
|
55831
|
-
const teamEntries = getTeamEntries(config, opts.team);
|
|
55832
|
-
let thresholdNum;
|
|
55833
|
-
if (opts.threshold !== void 0) {
|
|
55834
|
-
thresholdNum = parseInt(opts.threshold, 10);
|
|
55835
|
-
if (isNaN(thresholdNum)) {
|
|
55836
|
-
process.stderr.write(
|
|
55837
|
-
`Error: --threshold must be a number, got "${opts.threshold}"
|
|
55838
|
-
`
|
|
55839
|
-
);
|
|
55840
|
-
process.exit(1);
|
|
55841
|
-
}
|
|
55842
|
-
}
|
|
55843
|
-
let hasErrors = false;
|
|
55844
|
-
for (const [teamId, teamConfig] of teamEntries) {
|
|
55845
|
-
process.stdout.write(`
|
|
55846
|
-
--- Team: ${teamId} ---
|
|
55847
|
-
`);
|
|
55848
|
-
const resolved2 = await resolve4(teamConfig.dsl);
|
|
55849
|
-
const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
|
|
55850
|
-
const schemaResult2 = validateSchema(data2);
|
|
55851
|
-
if (!schemaResult2.success) {
|
|
55852
|
-
const issues = schemaResult2.diagnostics.map((d2) => ` ${d2.path}: ${d2.message}`).join("\n");
|
|
55853
|
-
process.stderr.write(`Schema validation failed:
|
|
55854
|
-
${issues}
|
|
55855
|
-
`);
|
|
55856
|
-
hasErrors = true;
|
|
55857
|
-
continue;
|
|
55858
|
-
}
|
|
55859
|
-
const result2 = score(schemaResult2.data);
|
|
55860
|
-
if (opts.format === "json") {
|
|
55861
|
-
process.stdout.write(JSON.stringify(result2, null, 2) + "\n");
|
|
55862
|
-
} else {
|
|
55863
|
-
process.stdout.write(formatText(result2) + "\n");
|
|
55864
|
-
}
|
|
55865
|
-
if (thresholdNum !== void 0 && result2.overall < thresholdNum) {
|
|
55866
|
-
process.stderr.write(
|
|
55867
|
-
`Score ${result2.overall} is below threshold ${thresholdNum}
|
|
55868
|
-
`
|
|
55869
|
-
);
|
|
55870
|
-
hasErrors = true;
|
|
55871
|
-
}
|
|
55872
|
-
}
|
|
55873
|
-
if (hasErrors) process.exit(1);
|
|
55874
|
-
return;
|
|
55875
|
-
}
|
|
55876
|
-
const dslPath = resolveDslPath(dir, DIR_DEFAULT4, config);
|
|
55877
|
-
const resolved = await resolve4(dslPath);
|
|
55878
|
-
const data = config?.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
55879
|
-
const schemaResult = validateSchema(data);
|
|
55880
|
-
if (!schemaResult.success) {
|
|
55881
|
-
const issues = schemaResult.diagnostics.map((d2) => ` ${d2.path}: ${d2.message}`).join("\n");
|
|
55882
|
-
process.stderr.write(`Schema validation failed:
|
|
55883
|
-
${issues}
|
|
55884
|
-
`);
|
|
55885
|
-
process.exit(1);
|
|
55886
|
-
}
|
|
55887
|
-
const result = score(schemaResult.data);
|
|
55888
|
-
if (opts.format === "json") {
|
|
55889
|
-
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
55890
|
-
} else {
|
|
55891
|
-
process.stdout.write(formatText(result) + "\n");
|
|
55892
|
-
}
|
|
55893
|
-
if (opts.threshold !== void 0) {
|
|
55894
|
-
const threshold = parseInt(opts.threshold, 10);
|
|
55895
|
-
if (isNaN(threshold)) {
|
|
55896
|
-
process.stderr.write(
|
|
55897
|
-
`Error: --threshold must be a number, got "${opts.threshold}"
|
|
55898
|
-
`
|
|
55899
|
-
);
|
|
55900
|
-
process.exit(1);
|
|
55901
|
-
}
|
|
55902
|
-
if (result.overall < threshold) {
|
|
55903
|
-
process.stderr.write(
|
|
55904
|
-
`Score ${result.overall} is below threshold ${threshold}
|
|
55905
|
-
`
|
|
55906
|
-
);
|
|
55907
|
-
process.exit(1);
|
|
55908
|
-
}
|
|
55909
|
-
}
|
|
55910
|
-
} catch (err) {
|
|
55911
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
55912
|
-
process.stderr.write(`Error: ${msg}
|
|
55913
|
-
`);
|
|
55914
|
-
process.exit(1);
|
|
55915
|
-
}
|
|
55761
|
+
function generateInterface(options) {
|
|
55762
|
+
if (!options.dsl.team_interface) {
|
|
55763
|
+
throw new Error("DSL has no team_interface section");
|
|
55916
55764
|
}
|
|
55917
|
-
);
|
|
55918
|
-
|
|
55919
|
-
|
|
55920
|
-
|
|
55921
|
-
|
|
55765
|
+
const doc = buildInterfaceDocument(options.dsl, (/* @__PURE__ */ new Date()).toISOString());
|
|
55766
|
+
const content = options.format === "json" ? `${JSON.stringify(doc, null, 2)}
|
|
55767
|
+
` : `${stringify(doc, { sortMapEntries: true })}
|
|
55768
|
+
`;
|
|
55769
|
+
const outputPath = options.output ?? "team-interface.yaml";
|
|
55770
|
+
return { outputPath, content };
|
|
55771
|
+
}
|
|
55922
55772
|
|
|
55923
55773
|
// src/auditor/context-builder.ts
|
|
55924
55774
|
import { readFile as readFile6 } from "fs/promises";
|
|
@@ -56673,11 +56523,579 @@ function computeExitCode(results, failOn) {
|
|
|
56673
56523
|
return 0;
|
|
56674
56524
|
}
|
|
56675
56525
|
|
|
56676
|
-
// src/cli/
|
|
56526
|
+
// src/cli/format.ts
|
|
56527
|
+
function formatDiagnostics(diagnostics, options) {
|
|
56528
|
+
if (options.quiet && diagnostics.length === 0) return "";
|
|
56529
|
+
if (options.format === "json") {
|
|
56530
|
+
return JSON.stringify(diagnostics, null, 2);
|
|
56531
|
+
}
|
|
56532
|
+
return diagnostics.map((d2) => {
|
|
56533
|
+
const severity = d2.severity ?? d2.code ?? "error";
|
|
56534
|
+
const rule = d2.ruleId ?? d2.code ?? "";
|
|
56535
|
+
return `${d2.path}: ${severity} [${rule}] ${d2.message}`;
|
|
56536
|
+
}).join("\n");
|
|
56537
|
+
}
|
|
56538
|
+
|
|
56539
|
+
// src/cli/multi-team.ts
|
|
56540
|
+
function isMultiTeamConfig(config) {
|
|
56541
|
+
return config.teams !== void 0 && Object.keys(config.teams).length > 0;
|
|
56542
|
+
}
|
|
56543
|
+
function getTeamEntries(config, teamFilter) {
|
|
56544
|
+
if (!config.teams) return [];
|
|
56545
|
+
const entries = Object.entries(config.teams);
|
|
56546
|
+
if (teamFilter) {
|
|
56547
|
+
const found = entries.filter(([k2]) => k2 === teamFilter);
|
|
56548
|
+
if (found.length === 0) {
|
|
56549
|
+
throw new Error(
|
|
56550
|
+
`Team "${teamFilter}" not found. Available teams: ${entries.map(([k2]) => k2).join(", ")}`
|
|
56551
|
+
);
|
|
56552
|
+
}
|
|
56553
|
+
return found;
|
|
56554
|
+
}
|
|
56555
|
+
return entries;
|
|
56556
|
+
}
|
|
56557
|
+
|
|
56558
|
+
// src/cli/commands/generate-interface.ts
|
|
56559
|
+
import { writeFileSync } from "fs";
|
|
56560
|
+
import { resolve as resolve7 } from "path";
|
|
56561
|
+
function runGenerateInterfaceCli(opts) {
|
|
56562
|
+
if (!opts.dsl.team_interface) {
|
|
56563
|
+
process.stderr.write("Error: DSL has no team_interface section.\n");
|
|
56564
|
+
process.exit(1);
|
|
56565
|
+
}
|
|
56566
|
+
const outputPath = resolve7(process.cwd(), opts.output ?? "team-interface.yaml");
|
|
56567
|
+
const result = generateInterface({
|
|
56568
|
+
dsl: opts.dsl,
|
|
56569
|
+
output: outputPath,
|
|
56570
|
+
dryRun: opts.dryRun,
|
|
56571
|
+
format: opts.format
|
|
56572
|
+
});
|
|
56573
|
+
if (opts.dryRun) {
|
|
56574
|
+
process.stdout.write(result.content);
|
|
56575
|
+
return;
|
|
56576
|
+
}
|
|
56577
|
+
writeFileSync(result.outputPath, result.content, "utf8");
|
|
56578
|
+
if (!opts.quiet) {
|
|
56579
|
+
process.stdout.write(`Wrote ${result.outputPath}
|
|
56580
|
+
`);
|
|
56581
|
+
}
|
|
56582
|
+
}
|
|
56583
|
+
|
|
56584
|
+
// src/cli/handlers.ts
|
|
56585
|
+
var DIR_DEFAULT = "agent-contracts.yaml";
|
|
56586
|
+
var handleResolve = async (dir, opts) => {
|
|
56587
|
+
try {
|
|
56588
|
+
const config = await loadConfig(opts.config);
|
|
56589
|
+
if (config !== null && isMultiTeamConfig(config)) {
|
|
56590
|
+
const teamEntries = getTeamEntries(config, opts.team);
|
|
56591
|
+
if (opts.format === "json") {
|
|
56592
|
+
const out = {};
|
|
56593
|
+
for (const [teamId, teamConfig] of teamEntries) {
|
|
56594
|
+
const result2 = await resolve4(teamConfig.dsl);
|
|
56595
|
+
let data2 = teamConfig.vars ? substituteVars(result2.data, teamConfig.vars) : result2.data;
|
|
56596
|
+
if (opts.expandDefaults) data2 = expandDefaults(data2);
|
|
56597
|
+
out[teamId] = data2;
|
|
56598
|
+
}
|
|
56599
|
+
process.stdout.write(JSON.stringify(out, null, 2) + "\n");
|
|
56600
|
+
} else {
|
|
56601
|
+
for (const [teamId, teamConfig] of teamEntries) {
|
|
56602
|
+
process.stdout.write(`
|
|
56603
|
+
--- Team: ${teamId} ---
|
|
56604
|
+
`);
|
|
56605
|
+
const result2 = await resolve4(teamConfig.dsl);
|
|
56606
|
+
let data2 = teamConfig.vars ? substituteVars(result2.data, teamConfig.vars) : result2.data;
|
|
56607
|
+
if (opts.expandDefaults) data2 = expandDefaults(data2);
|
|
56608
|
+
process.stdout.write(stringify3(data2));
|
|
56609
|
+
}
|
|
56610
|
+
}
|
|
56611
|
+
return;
|
|
56612
|
+
}
|
|
56613
|
+
const dslPath = resolveDslPath(dir ?? DIR_DEFAULT, DIR_DEFAULT, config);
|
|
56614
|
+
const result = await resolve4(dslPath);
|
|
56615
|
+
let data = config?.vars ? substituteVars(result.data, config.vars) : result.data;
|
|
56616
|
+
if (opts.expandDefaults) data = expandDefaults(data);
|
|
56617
|
+
if (opts.format === "json") {
|
|
56618
|
+
process.stdout.write(JSON.stringify(data, null, 2) + "\n");
|
|
56619
|
+
} else {
|
|
56620
|
+
process.stdout.write(stringify3(data));
|
|
56621
|
+
}
|
|
56622
|
+
} catch (err) {
|
|
56623
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56624
|
+
process.stderr.write(`Error: ${msg}
|
|
56625
|
+
`);
|
|
56626
|
+
process.exit(1);
|
|
56627
|
+
}
|
|
56628
|
+
};
|
|
56629
|
+
var handleValidate = async (dir, opts) => {
|
|
56630
|
+
try {
|
|
56631
|
+
const config = await loadConfig(opts.config);
|
|
56632
|
+
if (config !== null && isMultiTeamConfig(config)) {
|
|
56633
|
+
const teamEntries = getTeamEntries(config, opts.team);
|
|
56634
|
+
let hasErrors = false;
|
|
56635
|
+
let allTeamsFullyClean = true;
|
|
56636
|
+
for (const [teamId, teamConfig] of teamEntries) {
|
|
56637
|
+
if (!opts.quiet) process.stdout.write(`
|
|
56638
|
+
--- Team: ${teamId} ---
|
|
56639
|
+
`);
|
|
56640
|
+
const resolved2 = await resolve4(teamConfig.dsl);
|
|
56641
|
+
const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
|
|
56642
|
+
const schemaResult2 = validateSchema(data2);
|
|
56643
|
+
const schemaWarnings2 = schemaResult2.diagnostics.filter(
|
|
56644
|
+
(d2) => d2.severity === "warning"
|
|
56645
|
+
);
|
|
56646
|
+
if (!schemaResult2.success) {
|
|
56647
|
+
const output = formatDiagnostics(schemaResult2.diagnostics, {
|
|
56648
|
+
format: opts.format ?? "text",
|
|
56649
|
+
quiet: !!opts.quiet
|
|
56650
|
+
});
|
|
56651
|
+
if (output) process.stderr.write(output + "\n");
|
|
56652
|
+
hasErrors = true;
|
|
56653
|
+
allTeamsFullyClean = false;
|
|
56654
|
+
continue;
|
|
56655
|
+
}
|
|
56656
|
+
const refDiags2 = checkReferences(schemaResult2.data);
|
|
56657
|
+
const handoffDiags2 = validateHandoffSchemas(schemaResult2.data);
|
|
56658
|
+
const allDiags2 = [...refDiags2, ...handoffDiags2, ...schemaWarnings2];
|
|
56659
|
+
if (allDiags2.length > 0) {
|
|
56660
|
+
allTeamsFullyClean = false;
|
|
56661
|
+
const output = formatDiagnostics(allDiags2, {
|
|
56662
|
+
format: opts.format ?? "text",
|
|
56663
|
+
quiet: !!opts.quiet
|
|
56664
|
+
});
|
|
56665
|
+
if (output) process.stderr.write(output + "\n");
|
|
56666
|
+
const hasWarnings2 = allDiags2.some(
|
|
56667
|
+
(d2) => "severity" in d2 && d2.severity === "warning"
|
|
56668
|
+
);
|
|
56669
|
+
if (refDiags2.length > 0 || handoffDiags2.length > 0 || opts.strict && hasWarnings2) {
|
|
56670
|
+
hasErrors = true;
|
|
56671
|
+
}
|
|
56672
|
+
}
|
|
56673
|
+
}
|
|
56674
|
+
if (hasErrors) process.exit(1);
|
|
56675
|
+
if (!opts.quiet && allTeamsFullyClean) process.stdout.write("Validation passed.\n");
|
|
56676
|
+
return;
|
|
56677
|
+
}
|
|
56678
|
+
const dslPath = resolveDslPath(dir ?? DIR_DEFAULT, DIR_DEFAULT, config);
|
|
56679
|
+
const resolved = await resolve4(dslPath);
|
|
56680
|
+
const data = config?.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
56681
|
+
const schemaResult = validateSchema(data);
|
|
56682
|
+
const schemaWarnings = schemaResult.diagnostics.filter(
|
|
56683
|
+
(d2) => d2.severity === "warning"
|
|
56684
|
+
);
|
|
56685
|
+
if (!schemaResult.success) {
|
|
56686
|
+
const output = formatDiagnostics(schemaResult.diagnostics, {
|
|
56687
|
+
format: opts.format ?? "text",
|
|
56688
|
+
quiet: !!opts.quiet
|
|
56689
|
+
});
|
|
56690
|
+
if (output) process.stderr.write(output + "\n");
|
|
56691
|
+
process.exit(1);
|
|
56692
|
+
}
|
|
56693
|
+
const refDiags = checkReferences(schemaResult.data);
|
|
56694
|
+
const handoffDiags = validateHandoffSchemas(schemaResult.data);
|
|
56695
|
+
const allDiags = [...refDiags, ...handoffDiags, ...schemaWarnings];
|
|
56696
|
+
const hasWarnings = allDiags.some(
|
|
56697
|
+
(d2) => "severity" in d2 && d2.severity === "warning"
|
|
56698
|
+
);
|
|
56699
|
+
if (allDiags.length > 0) {
|
|
56700
|
+
const output = formatDiagnostics(allDiags, {
|
|
56701
|
+
format: opts.format ?? "text",
|
|
56702
|
+
quiet: !!opts.quiet
|
|
56703
|
+
});
|
|
56704
|
+
if (output) process.stderr.write(output + "\n");
|
|
56705
|
+
if (refDiags.length > 0 || handoffDiags.length > 0 || opts.strict && hasWarnings) {
|
|
56706
|
+
process.exit(1);
|
|
56707
|
+
}
|
|
56708
|
+
}
|
|
56709
|
+
if (!opts.quiet && allDiags.length === 0) process.stdout.write("Validation passed.\n");
|
|
56710
|
+
} catch (err) {
|
|
56711
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56712
|
+
process.stderr.write(`Error: ${msg}
|
|
56713
|
+
`);
|
|
56714
|
+
process.exit(1);
|
|
56715
|
+
}
|
|
56716
|
+
};
|
|
56717
|
+
var handleLint = async (dir, opts) => {
|
|
56718
|
+
try {
|
|
56719
|
+
const config = await loadConfig(opts.config);
|
|
56720
|
+
if (config !== null && isMultiTeamConfig(config)) {
|
|
56721
|
+
const teamEntries = getTeamEntries(config, opts.team);
|
|
56722
|
+
let hasErrors = false;
|
|
56723
|
+
let allClean = true;
|
|
56724
|
+
for (const [teamId, teamConfig] of teamEntries) {
|
|
56725
|
+
if (!opts.quiet) process.stdout.write(`
|
|
56726
|
+
--- Team: ${teamId} ---
|
|
56727
|
+
`);
|
|
56728
|
+
const resolved2 = await resolve4(teamConfig.dsl);
|
|
56729
|
+
const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
|
|
56730
|
+
const schemaResult2 = validateSchema(data2);
|
|
56731
|
+
const schemaWarnings2 = schemaResult2.diagnostics.filter(
|
|
56732
|
+
(d2) => d2.severity === "warning"
|
|
56733
|
+
);
|
|
56734
|
+
if (!schemaResult2.success) {
|
|
56735
|
+
const output = formatDiagnostics(schemaResult2.diagnostics, {
|
|
56736
|
+
format: opts.format ?? "text",
|
|
56737
|
+
quiet: !!opts.quiet
|
|
56738
|
+
});
|
|
56739
|
+
if (output) process.stderr.write(output + "\n");
|
|
56740
|
+
hasErrors = true;
|
|
56741
|
+
allClean = false;
|
|
56742
|
+
continue;
|
|
56743
|
+
}
|
|
56744
|
+
const tsDiagnostics2 = lint(schemaResult2.data);
|
|
56745
|
+
const spectralDiagnostics2 = await spectralLint(
|
|
56746
|
+
schemaResult2.data
|
|
56747
|
+
);
|
|
56748
|
+
const diagnostics2 = [...tsDiagnostics2, ...spectralDiagnostics2, ...schemaWarnings2];
|
|
56749
|
+
if (diagnostics2.length > 0) {
|
|
56750
|
+
allClean = false;
|
|
56751
|
+
const output = formatDiagnostics(diagnostics2, {
|
|
56752
|
+
format: opts.format ?? "text",
|
|
56753
|
+
quiet: !!opts.quiet
|
|
56754
|
+
});
|
|
56755
|
+
if (output) process.stderr.write(output + "\n");
|
|
56756
|
+
if (diagnostics2.some((d2) => d2.severity === "error")) hasErrors = true;
|
|
56757
|
+
if (opts.strict && diagnostics2.some((d2) => d2.severity === "warning")) hasErrors = true;
|
|
56758
|
+
}
|
|
56759
|
+
}
|
|
56760
|
+
if (hasErrors) process.exit(1);
|
|
56761
|
+
if (!opts.quiet && allClean) process.stdout.write("Lint passed.\n");
|
|
56762
|
+
return;
|
|
56763
|
+
}
|
|
56764
|
+
const dslPath = resolveDslPath(dir ?? DIR_DEFAULT, DIR_DEFAULT, config);
|
|
56765
|
+
const resolved = await resolve4(dslPath);
|
|
56766
|
+
const data = config?.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
56767
|
+
const schemaResult = validateSchema(data);
|
|
56768
|
+
const schemaWarnings = schemaResult.diagnostics.filter(
|
|
56769
|
+
(d2) => d2.severity === "warning"
|
|
56770
|
+
);
|
|
56771
|
+
if (!schemaResult.success) {
|
|
56772
|
+
const output = formatDiagnostics(schemaResult.diagnostics, {
|
|
56773
|
+
format: opts.format ?? "text",
|
|
56774
|
+
quiet: !!opts.quiet
|
|
56775
|
+
});
|
|
56776
|
+
if (output) process.stderr.write(output + "\n");
|
|
56777
|
+
process.exit(1);
|
|
56778
|
+
}
|
|
56779
|
+
const tsDiagnostics = lint(schemaResult.data);
|
|
56780
|
+
const spectralDiagnostics = await spectralLint(
|
|
56781
|
+
schemaResult.data
|
|
56782
|
+
);
|
|
56783
|
+
const diagnostics = [...tsDiagnostics, ...spectralDiagnostics, ...schemaWarnings];
|
|
56784
|
+
if (diagnostics.length > 0) {
|
|
56785
|
+
const output = formatDiagnostics(diagnostics, {
|
|
56786
|
+
format: opts.format ?? "text",
|
|
56787
|
+
quiet: !!opts.quiet
|
|
56788
|
+
});
|
|
56789
|
+
if (output) process.stderr.write(output + "\n");
|
|
56790
|
+
if (diagnostics.some((d2) => d2.severity === "error")) process.exit(1);
|
|
56791
|
+
if (opts.strict && diagnostics.some((d2) => d2.severity === "warning")) process.exit(1);
|
|
56792
|
+
}
|
|
56793
|
+
if (!opts.quiet && diagnostics.length === 0) process.stdout.write("Lint passed.\n");
|
|
56794
|
+
} catch (err) {
|
|
56795
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56796
|
+
process.stderr.write(`Error: ${msg}
|
|
56797
|
+
`);
|
|
56798
|
+
process.exit(1);
|
|
56799
|
+
}
|
|
56800
|
+
};
|
|
56801
|
+
var handleRender = async (opts) => {
|
|
56802
|
+
process.stderr.write(
|
|
56803
|
+
"Warning: 'render' is deprecated. Use 'agent-contracts generate templates' instead.\n"
|
|
56804
|
+
);
|
|
56805
|
+
await handleGenerate("templates", {
|
|
56806
|
+
config: opts.config,
|
|
56807
|
+
team: opts.team,
|
|
56808
|
+
check: opts.check,
|
|
56809
|
+
format: "yaml",
|
|
56810
|
+
dryRun: false,
|
|
56811
|
+
quiet: opts.quiet
|
|
56812
|
+
}, {});
|
|
56813
|
+
};
|
|
56814
|
+
var handleCheck = async (opts) => {
|
|
56815
|
+
let hasErrors = false;
|
|
56816
|
+
try {
|
|
56817
|
+
const config = await loadConfig(opts.config);
|
|
56818
|
+
if (!config) {
|
|
56819
|
+
process.stderr.write(
|
|
56820
|
+
"Error: agent-contracts.config.yaml not found. Use --config to specify path.\n"
|
|
56821
|
+
);
|
|
56822
|
+
process.exit(1);
|
|
56823
|
+
}
|
|
56824
|
+
if (isMultiTeamConfig(config)) {
|
|
56825
|
+
const teamEntries = getTeamEntries(config, opts.team);
|
|
56826
|
+
for (const [teamId, teamConfig] of teamEntries) {
|
|
56827
|
+
if (!opts.quiet) process.stderr.write(`
|
|
56828
|
+
--- Team: ${teamId} ---
|
|
56829
|
+
`);
|
|
56830
|
+
const resolved2 = await resolve4(teamConfig.dsl);
|
|
56831
|
+
const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
|
|
56832
|
+
const schemaResult2 = validateSchema(data2);
|
|
56833
|
+
const schemaWarnings2 = schemaResult2.diagnostics.filter((d2) => d2.severity === "warning");
|
|
56834
|
+
if (!schemaResult2.success) {
|
|
56835
|
+
const output = formatDiagnostics(schemaResult2.diagnostics, {
|
|
56836
|
+
format: opts.format ?? "text",
|
|
56837
|
+
quiet: !!opts.quiet
|
|
56838
|
+
});
|
|
56839
|
+
if (output) process.stderr.write(output + "\n");
|
|
56840
|
+
hasErrors = true;
|
|
56841
|
+
continue;
|
|
56842
|
+
}
|
|
56843
|
+
const refDiags2 = checkReferences(schemaResult2.data);
|
|
56844
|
+
const handoffDiags2 = validateHandoffSchemas(schemaResult2.data);
|
|
56845
|
+
const allRefDiags2 = [...refDiags2, ...handoffDiags2, ...schemaWarnings2];
|
|
56846
|
+
if (allRefDiags2.length > 0) {
|
|
56847
|
+
const output = formatDiagnostics(allRefDiags2, {
|
|
56848
|
+
format: opts.format ?? "text",
|
|
56849
|
+
quiet: !!opts.quiet
|
|
56850
|
+
});
|
|
56851
|
+
if (output) process.stderr.write(output + "\n");
|
|
56852
|
+
hasErrors = true;
|
|
56853
|
+
}
|
|
56854
|
+
const tsLintDiags2 = lint(schemaResult2.data);
|
|
56855
|
+
const spectralDiags2 = await spectralLint(
|
|
56856
|
+
schemaResult2.data
|
|
56857
|
+
);
|
|
56858
|
+
const lintDiags2 = [...tsLintDiags2, ...spectralDiags2];
|
|
56859
|
+
if (lintDiags2.length > 0) {
|
|
56860
|
+
const output = formatDiagnostics(lintDiags2, {
|
|
56861
|
+
format: opts.format ?? "text",
|
|
56862
|
+
quiet: !!opts.quiet
|
|
56863
|
+
});
|
|
56864
|
+
if (output) process.stderr.write(output + "\n");
|
|
56865
|
+
if (lintDiags2.some((d2) => d2.severity === "error")) hasErrors = true;
|
|
56866
|
+
if (opts.strict && lintDiags2.some((d2) => d2.severity === "warning")) hasErrors = true;
|
|
56867
|
+
}
|
|
56868
|
+
let renderOptions2;
|
|
56869
|
+
if (teamConfig.bindings.length > 0) {
|
|
56870
|
+
const loadedBindings = await loadBindings(teamConfig.bindings);
|
|
56871
|
+
renderOptions2 = { loadedBindings, activeGuardrailPolicy: teamConfig.activeGuardrailPolicy };
|
|
56872
|
+
}
|
|
56873
|
+
const drift2 = await checkDriftFromConfig(schemaResult2.data, config.renders, renderOptions2);
|
|
56874
|
+
if (drift2.hasDrift) {
|
|
56875
|
+
process.stderr.write(`Drift detected for team ${teamId} in:
|
|
56876
|
+
`);
|
|
56877
|
+
for (const f2 of drift2.diffs) process.stderr.write(` ${f2}
|
|
56878
|
+
`);
|
|
56879
|
+
hasErrors = true;
|
|
56880
|
+
}
|
|
56881
|
+
}
|
|
56882
|
+
if (!hasErrors) {
|
|
56883
|
+
for (const [teamId, teamConfig] of teamEntries) {
|
|
56884
|
+
const resolved2 = await resolve4(teamConfig.dsl);
|
|
56885
|
+
const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
|
|
56886
|
+
const schemaResult2 = validateSchema(data2);
|
|
56887
|
+
if (!schemaResult2.success || !schemaResult2.data) continue;
|
|
56888
|
+
const dsl = schemaResult2.data;
|
|
56889
|
+
const imports = dsl.imports;
|
|
56890
|
+
if (!imports) continue;
|
|
56891
|
+
for (const [importName, importDef] of Object.entries(imports)) {
|
|
56892
|
+
const interfacePathRel = importDef?.interface;
|
|
56893
|
+
if (typeof interfacePathRel !== "string") continue;
|
|
56894
|
+
const interfacePath = pathResolve(dirname7(teamConfig.dsl), interfacePathRel);
|
|
56895
|
+
try {
|
|
56896
|
+
await access2(interfacePath);
|
|
56897
|
+
} catch {
|
|
56898
|
+
process.stderr.write(
|
|
56899
|
+
`Cross-team error: Team "${teamId}" imports "${importName}" but interface file not found: ${interfacePath}
|
|
56900
|
+
`
|
|
56901
|
+
);
|
|
56902
|
+
hasErrors = true;
|
|
56903
|
+
}
|
|
56904
|
+
}
|
|
56905
|
+
}
|
|
56906
|
+
}
|
|
56907
|
+
if (hasErrors) process.exit(1);
|
|
56908
|
+
if (!opts.quiet) process.stdout.write("All checks passed.\n");
|
|
56909
|
+
return;
|
|
56910
|
+
}
|
|
56911
|
+
const resolved = await resolve4(config.dsl);
|
|
56912
|
+
const data = config.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
56913
|
+
const schemaResult = validateSchema(data);
|
|
56914
|
+
const schemaWarnings = schemaResult.diagnostics.filter((d2) => d2.severity === "warning");
|
|
56915
|
+
if (!schemaResult.success) {
|
|
56916
|
+
const output = formatDiagnostics(schemaResult.diagnostics, {
|
|
56917
|
+
format: opts.format ?? "text",
|
|
56918
|
+
quiet: !!opts.quiet
|
|
56919
|
+
});
|
|
56920
|
+
if (output) process.stderr.write(output + "\n");
|
|
56921
|
+
process.exit(1);
|
|
56922
|
+
}
|
|
56923
|
+
const refDiags = checkReferences(schemaResult.data);
|
|
56924
|
+
const handoffDiags = validateHandoffSchemas(schemaResult.data);
|
|
56925
|
+
const allRefDiags = [...refDiags, ...handoffDiags, ...schemaWarnings];
|
|
56926
|
+
if (allRefDiags.length > 0) {
|
|
56927
|
+
const output = formatDiagnostics(allRefDiags, {
|
|
56928
|
+
format: opts.format ?? "text",
|
|
56929
|
+
quiet: !!opts.quiet
|
|
56930
|
+
});
|
|
56931
|
+
if (output) process.stderr.write(output + "\n");
|
|
56932
|
+
hasErrors = true;
|
|
56933
|
+
}
|
|
56934
|
+
const tsLintDiags = lint(schemaResult.data);
|
|
56935
|
+
const spectralDiags = await spectralLint(
|
|
56936
|
+
schemaResult.data
|
|
56937
|
+
);
|
|
56938
|
+
const lintDiags = [...tsLintDiags, ...spectralDiags];
|
|
56939
|
+
if (lintDiags.length > 0) {
|
|
56940
|
+
const output = formatDiagnostics(lintDiags, {
|
|
56941
|
+
format: opts.format ?? "text",
|
|
56942
|
+
quiet: !!opts.quiet
|
|
56943
|
+
});
|
|
56944
|
+
if (output) process.stderr.write(output + "\n");
|
|
56945
|
+
if (lintDiags.some((d2) => d2.severity === "error")) hasErrors = true;
|
|
56946
|
+
if (opts.strict && lintDiags.some((d2) => d2.severity === "warning")) hasErrors = true;
|
|
56947
|
+
}
|
|
56948
|
+
let renderOptions;
|
|
56949
|
+
if (config.bindings.length > 0) {
|
|
56950
|
+
const loadedBindings = await loadBindings(config.bindings);
|
|
56951
|
+
renderOptions = { loadedBindings, activeGuardrailPolicy: config.activeGuardrailPolicy };
|
|
56952
|
+
}
|
|
56953
|
+
const drift = await checkDriftFromConfig(schemaResult.data, config.renders, renderOptions);
|
|
56954
|
+
if (drift.hasDrift) {
|
|
56955
|
+
process.stderr.write("Drift detected in:\n");
|
|
56956
|
+
for (const f2 of drift.diffs) process.stderr.write(` ${f2}
|
|
56957
|
+
`);
|
|
56958
|
+
hasErrors = true;
|
|
56959
|
+
}
|
|
56960
|
+
if (schemaResult.data.team_interface) {
|
|
56961
|
+
const interfacePath = join3(config.configDir, "team-interface.yaml");
|
|
56962
|
+
if (existsSync(interfacePath)) {
|
|
56963
|
+
const result = generateInterface({ dsl: schemaResult.data, dryRun: true, format: "yaml" });
|
|
56964
|
+
const existing = readFileSync(interfacePath, "utf8");
|
|
56965
|
+
const normalize = (raw) => {
|
|
56966
|
+
try {
|
|
56967
|
+
const parsed = parseYaml4(raw);
|
|
56968
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
56969
|
+
const { generated_at: _t, ...rest } = parsed;
|
|
56970
|
+
return `${stringify3(rest, { sortMapEntries: true })}
|
|
56971
|
+
`;
|
|
56972
|
+
}
|
|
56973
|
+
} catch {
|
|
56974
|
+
}
|
|
56975
|
+
return raw.trim();
|
|
56976
|
+
};
|
|
56977
|
+
if (normalize(existing) !== normalize(result.content)) {
|
|
56978
|
+
process.stderr.write("Drift detected in team-interface.yaml\n");
|
|
56979
|
+
hasErrors = true;
|
|
56980
|
+
}
|
|
56981
|
+
}
|
|
56982
|
+
}
|
|
56983
|
+
if (hasErrors) process.exit(1);
|
|
56984
|
+
if (!opts.quiet) process.stdout.write("All checks passed.\n");
|
|
56985
|
+
} catch (err) {
|
|
56986
|
+
if (err instanceof ConfigLoadError) {
|
|
56987
|
+
process.stderr.write(`Config error: ${err.message}
|
|
56988
|
+
`);
|
|
56989
|
+
process.exit(1);
|
|
56990
|
+
}
|
|
56991
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56992
|
+
process.stderr.write(`Error: ${msg}
|
|
56993
|
+
`);
|
|
56994
|
+
process.exit(1);
|
|
56995
|
+
}
|
|
56996
|
+
};
|
|
56997
|
+
function formatScoreText(result) {
|
|
56998
|
+
const lines = [];
|
|
56999
|
+
lines.push(`DSL Completeness Score: ${result.overall}/100`);
|
|
57000
|
+
lines.push("");
|
|
57001
|
+
for (const d2 of result.dimensions) {
|
|
57002
|
+
const detail = d2.total > 0 ? ` (${d2.score}/${d2.total} ${d2.id.split("-")[0]})` : "";
|
|
57003
|
+
lines.push(` ${d2.label.padEnd(40)} ${String(d2.percent).padStart(3)}%${detail}`);
|
|
57004
|
+
}
|
|
57005
|
+
const allRecs = result.dimensions.flatMap((d2) => d2.recommendations);
|
|
57006
|
+
if (allRecs.length > 0) {
|
|
57007
|
+
lines.push("");
|
|
57008
|
+
lines.push("Recommendations:");
|
|
57009
|
+
for (const rec of allRecs) lines.push(` - ${rec}`);
|
|
57010
|
+
}
|
|
57011
|
+
return lines.join("\n");
|
|
57012
|
+
}
|
|
57013
|
+
var handleScore = async (dir, opts) => {
|
|
57014
|
+
try {
|
|
57015
|
+
const config = await loadConfig(opts.config);
|
|
57016
|
+
if (config !== null && isMultiTeamConfig(config)) {
|
|
57017
|
+
const teamEntries = getTeamEntries(config, opts.team);
|
|
57018
|
+
let thresholdNum;
|
|
57019
|
+
if (opts.threshold !== void 0) {
|
|
57020
|
+
thresholdNum = parseInt(String(opts.threshold), 10);
|
|
57021
|
+
if (isNaN(thresholdNum)) {
|
|
57022
|
+
process.stderr.write(`Error: --threshold must be a number, got "${opts.threshold}"
|
|
57023
|
+
`);
|
|
57024
|
+
process.exit(1);
|
|
57025
|
+
}
|
|
57026
|
+
}
|
|
57027
|
+
let hasErrors = false;
|
|
57028
|
+
for (const [teamId, teamConfig] of teamEntries) {
|
|
57029
|
+
process.stdout.write(`
|
|
57030
|
+
--- Team: ${teamId} ---
|
|
57031
|
+
`);
|
|
57032
|
+
const resolved2 = await resolve4(teamConfig.dsl);
|
|
57033
|
+
const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
|
|
57034
|
+
const schemaResult2 = validateSchema(data2);
|
|
57035
|
+
if (!schemaResult2.success) {
|
|
57036
|
+
const issues = schemaResult2.diagnostics.map((d2) => ` ${d2.path}: ${d2.message}`).join("\n");
|
|
57037
|
+
process.stderr.write(`Schema validation failed:
|
|
57038
|
+
${issues}
|
|
57039
|
+
`);
|
|
57040
|
+
hasErrors = true;
|
|
57041
|
+
continue;
|
|
57042
|
+
}
|
|
57043
|
+
const result2 = score(schemaResult2.data);
|
|
57044
|
+
if (opts.format === "json") {
|
|
57045
|
+
process.stdout.write(JSON.stringify(result2, null, 2) + "\n");
|
|
57046
|
+
} else {
|
|
57047
|
+
process.stdout.write(formatScoreText(result2) + "\n");
|
|
57048
|
+
}
|
|
57049
|
+
if (thresholdNum !== void 0 && result2.overall < thresholdNum) {
|
|
57050
|
+
process.stderr.write(`Score ${result2.overall} is below threshold ${thresholdNum}
|
|
57051
|
+
`);
|
|
57052
|
+
hasErrors = true;
|
|
57053
|
+
}
|
|
57054
|
+
}
|
|
57055
|
+
if (hasErrors) process.exit(1);
|
|
57056
|
+
return;
|
|
57057
|
+
}
|
|
57058
|
+
const dslPath = resolveDslPath(dir ?? DIR_DEFAULT, DIR_DEFAULT, config);
|
|
57059
|
+
const resolved = await resolve4(dslPath);
|
|
57060
|
+
const data = config?.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
|
|
57061
|
+
const schemaResult = validateSchema(data);
|
|
57062
|
+
if (!schemaResult.success) {
|
|
57063
|
+
const issues = schemaResult.diagnostics.map((d2) => ` ${d2.path}: ${d2.message}`).join("\n");
|
|
57064
|
+
process.stderr.write(`Schema validation failed:
|
|
57065
|
+
${issues}
|
|
57066
|
+
`);
|
|
57067
|
+
process.exit(1);
|
|
57068
|
+
}
|
|
57069
|
+
const result = score(schemaResult.data);
|
|
57070
|
+
if (opts.format === "json") {
|
|
57071
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
57072
|
+
} else {
|
|
57073
|
+
process.stdout.write(formatScoreText(result) + "\n");
|
|
57074
|
+
}
|
|
57075
|
+
if (opts.threshold !== void 0) {
|
|
57076
|
+
const threshold = parseInt(String(opts.threshold), 10);
|
|
57077
|
+
if (isNaN(threshold)) {
|
|
57078
|
+
process.stderr.write(`Error: --threshold must be a number, got "${opts.threshold}"
|
|
57079
|
+
`);
|
|
57080
|
+
process.exit(1);
|
|
57081
|
+
}
|
|
57082
|
+
if (result.overall < threshold) {
|
|
57083
|
+
process.stderr.write(`Score ${result.overall} is below threshold ${threshold}
|
|
57084
|
+
`);
|
|
57085
|
+
process.exit(1);
|
|
57086
|
+
}
|
|
57087
|
+
}
|
|
57088
|
+
} catch (err) {
|
|
57089
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
57090
|
+
process.stderr.write(`Error: ${msg}
|
|
57091
|
+
`);
|
|
57092
|
+
process.exit(1);
|
|
57093
|
+
}
|
|
57094
|
+
};
|
|
56677
57095
|
var AUDIT_TYPES = ["render", "dsl", "prompt", "all"];
|
|
56678
|
-
function parseAuditConfig(
|
|
56679
|
-
if (!
|
|
56680
|
-
const audit =
|
|
57096
|
+
function parseAuditConfig(configObj) {
|
|
57097
|
+
if (!configObj) return {};
|
|
57098
|
+
const audit = configObj;
|
|
56681
57099
|
return {
|
|
56682
57100
|
adapter: audit.adapter,
|
|
56683
57101
|
model: audit.model,
|
|
@@ -56685,7 +57103,7 @@ function parseAuditConfig(config) {
|
|
|
56685
57103
|
cache_dir: audit.cache_dir
|
|
56686
57104
|
};
|
|
56687
57105
|
}
|
|
56688
|
-
async function runAuditForDsl(dslPath, vars, configObj, auditType,
|
|
57106
|
+
async function runAuditForDsl(dslPath, vars, configObj, auditType, auditOpts, failOn) {
|
|
56689
57107
|
const resolved = await resolve4(dslPath);
|
|
56690
57108
|
const data = vars ? substituteVars(resolved.data, vars) : resolved.data;
|
|
56691
57109
|
const schemaResult = validateSchema(data);
|
|
@@ -56696,122 +57114,283 @@ async function runAuditForDsl(dslPath, vars, configObj, auditType, opts, failOn)
|
|
|
56696
57114
|
const auditConfig = parseAuditConfig(
|
|
56697
57115
|
configObj.audit
|
|
56698
57116
|
);
|
|
56699
|
-
if (
|
|
56700
|
-
if (
|
|
57117
|
+
if (auditOpts.adapter) auditConfig.adapter = auditOpts.adapter;
|
|
57118
|
+
if (auditOpts.model) auditConfig.model = auditOpts.model;
|
|
56701
57119
|
if (auditType === "all") {
|
|
56702
57120
|
const results = await runAllAudits(schemaResult.data, configObj, auditConfig, {
|
|
56703
|
-
format:
|
|
56704
|
-
scope:
|
|
56705
|
-
dryRun:
|
|
57121
|
+
format: auditOpts.format,
|
|
57122
|
+
scope: auditOpts.scope,
|
|
57123
|
+
dryRun: auditOpts.dryRun
|
|
56706
57124
|
});
|
|
56707
57125
|
let output2;
|
|
56708
|
-
if (
|
|
56709
|
-
output2 = results.map(
|
|
56710
|
-
(r3) => `
|
|
57126
|
+
if (auditOpts.dryRun) {
|
|
57127
|
+
output2 = results.map((r3) => `
|
|
56711
57128
|
--- Audit prompt: ${r3.auditType} ---
|
|
56712
57129
|
${r3.prompt}
|
|
56713
|
-
`
|
|
56714
|
-
).join("");
|
|
57130
|
+
`).join("");
|
|
56715
57131
|
} else {
|
|
56716
|
-
output2 = formatAuditResults(results,
|
|
57132
|
+
output2 = formatAuditResults(results, auditOpts.format) + "\n";
|
|
56717
57133
|
}
|
|
56718
57134
|
return { exitCode: computeExitCode(results, failOn), output: output2 };
|
|
56719
57135
|
}
|
|
56720
57136
|
const result = await runAudit(schemaResult.data, configObj, auditConfig, {
|
|
56721
57137
|
auditType,
|
|
56722
|
-
format:
|
|
56723
|
-
scope:
|
|
56724
|
-
dryRun:
|
|
57138
|
+
format: auditOpts.format,
|
|
57139
|
+
scope: auditOpts.scope,
|
|
57140
|
+
dryRun: auditOpts.dryRun
|
|
56725
57141
|
});
|
|
56726
57142
|
let output;
|
|
56727
|
-
if (
|
|
57143
|
+
if (auditOpts.dryRun) {
|
|
56728
57144
|
output = result.prompt + "\n";
|
|
56729
57145
|
} else {
|
|
56730
|
-
output = formatAuditResult(result,
|
|
57146
|
+
output = formatAuditResult(result, auditOpts.format) + "\n";
|
|
56731
57147
|
}
|
|
56732
57148
|
return { exitCode: computeExitCode([result], failOn), output };
|
|
56733
57149
|
}
|
|
56734
|
-
var
|
|
56735
|
-
|
|
56736
|
-
|
|
56737
|
-
|
|
56738
|
-
|
|
57150
|
+
var handleAudit = async (type, opts) => {
|
|
57151
|
+
const auditType = type ?? "all";
|
|
57152
|
+
if (!AUDIT_TYPES.includes(auditType)) {
|
|
57153
|
+
process.stderr.write(
|
|
57154
|
+
`Unknown audit type: "${auditType}". Use one of: ${AUDIT_TYPES.join(", ")}
|
|
56739
57155
|
`
|
|
57156
|
+
);
|
|
57157
|
+
process.exit(1);
|
|
57158
|
+
}
|
|
57159
|
+
const format2 = opts.reportFormat ?? opts.format ?? "text";
|
|
57160
|
+
try {
|
|
57161
|
+
const config = await loadConfig(opts.config);
|
|
57162
|
+
if (!config) {
|
|
57163
|
+
process.stderr.write(
|
|
57164
|
+
"Error: agent-contracts.config.yaml not found. Use --config to specify path.\n"
|
|
56740
57165
|
);
|
|
56741
57166
|
process.exit(1);
|
|
56742
57167
|
}
|
|
56743
|
-
|
|
56744
|
-
|
|
56745
|
-
|
|
56746
|
-
|
|
57168
|
+
if (isMultiTeamConfig(config)) {
|
|
57169
|
+
const teamEntries = getTeamEntries(config, opts.team);
|
|
57170
|
+
let maxExit = 0;
|
|
57171
|
+
const allOutput = [];
|
|
57172
|
+
for (const [teamId, teamConfig] of teamEntries) {
|
|
57173
|
+
process.stderr.write(`
|
|
57174
|
+
--- Team: ${teamId} ---
|
|
57175
|
+
`);
|
|
57176
|
+
const result2 = await runAuditForDsl(
|
|
57177
|
+
teamConfig.dsl,
|
|
57178
|
+
teamConfig.vars,
|
|
57179
|
+
config,
|
|
57180
|
+
auditType,
|
|
57181
|
+
{ format: format2, scope: opts.scope, dryRun: !!opts.dryRun, adapter: opts.adapter, model: opts.model },
|
|
57182
|
+
opts.failOn
|
|
57183
|
+
);
|
|
57184
|
+
process.stdout.write(result2.output);
|
|
57185
|
+
allOutput.push(result2.output);
|
|
57186
|
+
if (result2.exitCode > maxExit) maxExit = result2.exitCode;
|
|
57187
|
+
}
|
|
57188
|
+
if (opts.output) writeFileSync2(opts.output, allOutput.join(""), "utf8");
|
|
57189
|
+
process.exit(maxExit);
|
|
57190
|
+
}
|
|
57191
|
+
const result = await runAuditForDsl(
|
|
57192
|
+
config.dsl,
|
|
57193
|
+
config.vars,
|
|
57194
|
+
config,
|
|
57195
|
+
auditType,
|
|
57196
|
+
{ format: format2, scope: opts.scope, dryRun: !!opts.dryRun, adapter: opts.adapter, model: opts.model },
|
|
57197
|
+
opts.failOn
|
|
57198
|
+
);
|
|
57199
|
+
process.stdout.write(result.output);
|
|
57200
|
+
if (opts.output) writeFileSync2(opts.output, result.output, "utf8");
|
|
57201
|
+
process.exit(result.exitCode);
|
|
57202
|
+
} catch (err) {
|
|
57203
|
+
if (err instanceof ConfigLoadError) {
|
|
57204
|
+
process.stderr.write(`Config error: ${err.message}
|
|
57205
|
+
`);
|
|
57206
|
+
process.exit(1);
|
|
57207
|
+
}
|
|
57208
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
57209
|
+
process.stderr.write(`Error: ${msg}
|
|
57210
|
+
`);
|
|
57211
|
+
if (msg.includes("not installed")) process.exit(11);
|
|
57212
|
+
if (msg.includes("adapter") || msg.includes("API")) process.exit(12);
|
|
57213
|
+
process.exit(1);
|
|
57214
|
+
}
|
|
57215
|
+
};
|
|
57216
|
+
var VALID_TYPES = ["templates", "guardrails", "interface"];
|
|
57217
|
+
function resolvedConfigForTeam(workspace, teamConfig) {
|
|
57218
|
+
return {
|
|
57219
|
+
dsl: "",
|
|
57220
|
+
vars: teamConfig.vars,
|
|
57221
|
+
renders: workspace.renders,
|
|
57222
|
+
configDir: workspace.configDir,
|
|
57223
|
+
bindings: teamConfig.bindings,
|
|
57224
|
+
activeGuardrailPolicy: teamConfig.activeGuardrailPolicy,
|
|
57225
|
+
paths: teamConfig.paths
|
|
57226
|
+
};
|
|
57227
|
+
}
|
|
57228
|
+
var handleGenerate = async (type, opts) => {
|
|
57229
|
+
if (type !== void 0 && !VALID_TYPES.includes(type)) {
|
|
57230
|
+
process.stderr.write(`Unknown generate type: ${type}
|
|
57231
|
+
`);
|
|
57232
|
+
process.exit(1);
|
|
57233
|
+
}
|
|
57234
|
+
const fmt = opts.format ?? "yaml";
|
|
57235
|
+
if (fmt !== "yaml" && fmt !== "json") {
|
|
57236
|
+
process.stderr.write(`Invalid --format: expected yaml or json, got ${fmt}
|
|
57237
|
+
`);
|
|
57238
|
+
process.exit(1);
|
|
57239
|
+
}
|
|
57240
|
+
const normalizedType = type;
|
|
57241
|
+
const targets = {
|
|
57242
|
+
templates: normalizedType === void 0 || normalizedType === "templates",
|
|
57243
|
+
guardrails: normalizedType === void 0 || normalizedType === "guardrails",
|
|
57244
|
+
interface: normalizedType === void 0 || normalizedType === "interface"
|
|
57245
|
+
};
|
|
57246
|
+
try {
|
|
57247
|
+
const config = await loadConfig(opts.config);
|
|
57248
|
+
if (!config) {
|
|
57249
|
+
process.stderr.write(
|
|
57250
|
+
"Error: agent-contracts.config.yaml not found. Use --config to specify path.\n"
|
|
57251
|
+
);
|
|
57252
|
+
process.exit(1);
|
|
57253
|
+
}
|
|
57254
|
+
const processTeam = async (teamConfig, teamLabel) => {
|
|
57255
|
+
let exitWithError = false;
|
|
57256
|
+
const resolved = await resolve4(teamConfig.dsl);
|
|
57257
|
+
const data = teamConfig.vars ? substituteVars(resolved.data, teamConfig.vars) : resolved.data;
|
|
57258
|
+
const schemaResult = validateSchema(data);
|
|
57259
|
+
if (!schemaResult.success) {
|
|
56747
57260
|
process.stderr.write(
|
|
56748
|
-
|
|
57261
|
+
`Schema validation failed${teamLabel ? ` for team ${teamLabel}` : ""}. Run 'agent-contracts validate' for details.
|
|
57262
|
+
`
|
|
56749
57263
|
);
|
|
56750
|
-
|
|
57264
|
+
return true;
|
|
56751
57265
|
}
|
|
56752
|
-
if (
|
|
56753
|
-
|
|
56754
|
-
|
|
56755
|
-
|
|
56756
|
-
|
|
56757
|
-
|
|
56758
|
-
|
|
57266
|
+
if (targets.templates) {
|
|
57267
|
+
let renderOptions;
|
|
57268
|
+
if (teamConfig.bindings.length > 0) {
|
|
57269
|
+
const loadedBindings = await loadBindings(teamConfig.bindings);
|
|
57270
|
+
renderOptions = { loadedBindings, activeGuardrailPolicy: teamConfig.activeGuardrailPolicy };
|
|
57271
|
+
}
|
|
57272
|
+
if (opts.check) {
|
|
57273
|
+
const drift = await checkDriftFromConfig(schemaResult.data, config.renders, renderOptions);
|
|
57274
|
+
if (drift.hasDrift) {
|
|
57275
|
+
process.stderr.write(`Drift detected${teamLabel ? ` for team ${teamLabel}` : ""} in the following files:
|
|
56759
57276
|
`);
|
|
56760
|
-
|
|
56761
|
-
teamConfig.dsl,
|
|
56762
|
-
teamConfig.vars,
|
|
56763
|
-
config,
|
|
56764
|
-
type,
|
|
56765
|
-
{ format: format2, scope: opts.scope, dryRun: opts.dryRun, adapter: opts.adapter, model: opts.model },
|
|
56766
|
-
opts.failOn
|
|
56767
|
-
);
|
|
56768
|
-
process.stdout.write(result2.output);
|
|
56769
|
-
allOutput.push(result2.output);
|
|
56770
|
-
if (result2.exitCode > maxExit) maxExit = result2.exitCode;
|
|
56771
|
-
}
|
|
56772
|
-
if (opts.output) writeFileSync2(opts.output, allOutput.join(""), "utf8");
|
|
56773
|
-
process.exit(maxExit);
|
|
56774
|
-
}
|
|
56775
|
-
const result = await runAuditForDsl(
|
|
56776
|
-
config.dsl,
|
|
56777
|
-
config.vars,
|
|
56778
|
-
config,
|
|
56779
|
-
type,
|
|
56780
|
-
{ format: format2, scope: opts.scope, dryRun: opts.dryRun, adapter: opts.adapter, model: opts.model },
|
|
56781
|
-
opts.failOn
|
|
56782
|
-
);
|
|
56783
|
-
process.stdout.write(result.output);
|
|
56784
|
-
if (opts.output) writeFileSync2(opts.output, result.output, "utf8");
|
|
56785
|
-
process.exit(result.exitCode);
|
|
56786
|
-
} catch (err) {
|
|
56787
|
-
if (err instanceof ConfigLoadError) {
|
|
56788
|
-
process.stderr.write(`Config error: ${err.message}
|
|
57277
|
+
for (const f2 of drift.diffs) process.stderr.write(` ${f2}
|
|
56789
57278
|
`);
|
|
56790
|
-
|
|
57279
|
+
exitWithError = true;
|
|
57280
|
+
} else if (!opts.quiet) {
|
|
57281
|
+
process.stdout.write("No drift detected.\n");
|
|
57282
|
+
}
|
|
57283
|
+
} else {
|
|
57284
|
+
const files = await renderFromConfig(schemaResult.data, config.renders, renderOptions);
|
|
57285
|
+
if (!opts.quiet) {
|
|
57286
|
+
process.stdout.write(`Rendered ${files.length} file(s):
|
|
57287
|
+
`);
|
|
57288
|
+
for (const f2 of files) process.stdout.write(` ${f2}
|
|
57289
|
+
`);
|
|
57290
|
+
}
|
|
57291
|
+
}
|
|
56791
57292
|
}
|
|
56792
|
-
|
|
56793
|
-
|
|
57293
|
+
if (targets.interface) {
|
|
57294
|
+
if (schemaResult.data.team_interface) {
|
|
57295
|
+
runGenerateInterfaceCli({
|
|
57296
|
+
dsl: schemaResult.data,
|
|
57297
|
+
output: teamConfig.interfaceOutput ?? opts.output,
|
|
57298
|
+
dryRun: !!opts.dryRun,
|
|
57299
|
+
format: fmt,
|
|
57300
|
+
quiet: !!opts.quiet
|
|
57301
|
+
});
|
|
57302
|
+
} else if (normalizedType === "interface") {
|
|
57303
|
+
process.stderr.write("Error: DSL has no team_interface section.\n");
|
|
57304
|
+
exitWithError = true;
|
|
57305
|
+
}
|
|
57306
|
+
}
|
|
57307
|
+
if (targets.guardrails) {
|
|
57308
|
+
const loadedBindings = await loadBindings(teamConfig.bindings);
|
|
57309
|
+
const cfgForTeam = teamLabel ? resolvedConfigForTeam(config, teamConfig) : config;
|
|
57310
|
+
const result = await generateGuardrails({
|
|
57311
|
+
dsl: schemaResult.data,
|
|
57312
|
+
config: cfgForTeam,
|
|
57313
|
+
loadedBindings,
|
|
57314
|
+
filterBindings: opts.binding ? [opts.binding] : void 0,
|
|
57315
|
+
dryRun: !!opts.dryRun
|
|
57316
|
+
});
|
|
57317
|
+
const errors = result.diagnostics.filter((d2) => d2.severity === "error");
|
|
57318
|
+
const warnings = result.diagnostics.filter((d2) => d2.severity === "warning");
|
|
57319
|
+
const infos = result.diagnostics.filter((d2) => d2.severity === "info");
|
|
57320
|
+
if (errors.length > 0) {
|
|
57321
|
+
process.stderr.write(`Errors${teamLabel ? ` (team ${teamLabel})` : ""}:
|
|
57322
|
+
`);
|
|
57323
|
+
for (const d2 of errors) process.stderr.write(` error [${d2.path}] ${d2.message}
|
|
57324
|
+
`);
|
|
57325
|
+
exitWithError = true;
|
|
57326
|
+
}
|
|
57327
|
+
if (warnings.length > 0 && !opts.quiet) {
|
|
57328
|
+
process.stderr.write(`Warnings${teamLabel ? ` (team ${teamLabel})` : ""}:
|
|
57329
|
+
`);
|
|
57330
|
+
for (const d2 of warnings) process.stderr.write(` warning [${d2.path}] ${d2.message}
|
|
57331
|
+
`);
|
|
57332
|
+
}
|
|
57333
|
+
if (infos.length > 0 && !opts.quiet) {
|
|
57334
|
+
for (const d2 of infos) process.stderr.write(` info [${d2.path}] ${d2.message}
|
|
57335
|
+
`);
|
|
57336
|
+
}
|
|
57337
|
+
if (!opts.quiet) {
|
|
57338
|
+
const action = opts.dryRun ? "Would generate" : "Generated";
|
|
57339
|
+
process.stdout.write(`${action} ${result.outputFiles.length} file(s):
|
|
57340
|
+
`);
|
|
57341
|
+
for (const f2 of result.outputFiles) process.stdout.write(` ${f2}
|
|
57342
|
+
`);
|
|
57343
|
+
}
|
|
57344
|
+
}
|
|
57345
|
+
return exitWithError;
|
|
57346
|
+
};
|
|
57347
|
+
if (isMultiTeamConfig(config)) {
|
|
57348
|
+
const teamEntries = getTeamEntries(config, opts.team);
|
|
57349
|
+
let exitWithError = false;
|
|
57350
|
+
for (const [teamId, teamConfig] of teamEntries) {
|
|
57351
|
+
if (!opts.quiet) process.stdout.write(`
|
|
57352
|
+
--- Team: ${teamId} ---
|
|
57353
|
+
`);
|
|
57354
|
+
if (await processTeam(teamConfig, teamId)) exitWithError = true;
|
|
57355
|
+
}
|
|
57356
|
+
if (exitWithError) process.exit(1);
|
|
57357
|
+
return;
|
|
57358
|
+
}
|
|
57359
|
+
const singleTeamConfig = {
|
|
57360
|
+
dsl: config.dsl,
|
|
57361
|
+
vars: config.vars,
|
|
57362
|
+
bindings: config.bindings,
|
|
57363
|
+
activeGuardrailPolicy: config.activeGuardrailPolicy,
|
|
57364
|
+
paths: config.paths
|
|
57365
|
+
};
|
|
57366
|
+
if (await processTeam(singleTeamConfig, void 0)) process.exit(1);
|
|
57367
|
+
} catch (err) {
|
|
57368
|
+
if (err instanceof ConfigLoadError) {
|
|
57369
|
+
process.stderr.write(`Config error: ${err.message}
|
|
56794
57370
|
`);
|
|
56795
|
-
if (msg.includes("not installed")) process.exit(11);
|
|
56796
|
-
if (msg.includes("adapter") || msg.includes("API")) process.exit(12);
|
|
56797
57371
|
process.exit(1);
|
|
56798
57372
|
}
|
|
57373
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
57374
|
+
process.stderr.write(`Error: ${msg}
|
|
57375
|
+
`);
|
|
57376
|
+
process.exit(1);
|
|
56799
57377
|
}
|
|
56800
|
-
|
|
57378
|
+
};
|
|
57379
|
+
var handlers = {
|
|
57380
|
+
resolve: handleResolve,
|
|
57381
|
+
validate: handleValidate,
|
|
57382
|
+
lint: handleLint,
|
|
57383
|
+
render: handleRender,
|
|
57384
|
+
check: handleCheck,
|
|
57385
|
+
score: handleScore,
|
|
57386
|
+
audit: handleAudit,
|
|
57387
|
+
generate: handleGenerate
|
|
57388
|
+
};
|
|
56801
57389
|
|
|
56802
57390
|
// src/cli/cli.ts
|
|
56803
57391
|
var __dirname = dirname8(fileURLToPath(import.meta.url));
|
|
56804
57392
|
var pkg = JSON.parse(readFileSync2(resolve8(__dirname, "../package.json"), "utf8"));
|
|
56805
|
-
var program =
|
|
56806
|
-
program.name("agent-contracts").description("Agent contracts tooling \u2014 validate, lint, render DSL files").version(pkg.version);
|
|
56807
|
-
program.addCommand(resolveCommand);
|
|
56808
|
-
program.addCommand(validateCommand);
|
|
56809
|
-
program.addCommand(lintCommand);
|
|
56810
|
-
program.addCommand(renderCommand);
|
|
56811
|
-
program.addCommand(checkCommand);
|
|
56812
|
-
program.addCommand(generateGuardrailsCommand);
|
|
56813
|
-
program.addCommand(scoreCommand);
|
|
56814
|
-
program.addCommand(auditCommand);
|
|
57393
|
+
var program = createProgram(handlers, pkg.version);
|
|
56815
57394
|
program.parse();
|
|
56816
57395
|
/*! Bundled license information:
|
|
56817
57396
|
|