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/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 = stringify5;
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 stringify5(value, replacer, spacer) {
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 stringify5 = require_stable();
7986
- module.exports = stringify5;
7987
- stringify5.default = stringify5;
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 stringify5 = JSON.stringify;
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(stringify5(node.value), node);
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)(require_dist7());
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 require_dist13 = __commonJS({
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/commands/resolve.ts
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(require_dist13(), 1);
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/cli/commands/render.ts
54384
- var renderCommand = new Command4("render").description("Render resolved DSL with Handlebars templates (requires config)").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 drift without writing files", false).option("--quiet", "Suppress output on success", false).action(
54385
- async (opts) => {
54386
- try {
54387
- const config = await loadConfig(opts.config);
54388
- if (!config) {
54389
- process.stderr.write(
54390
- "Error: agent-contracts.config.yaml not found. Use --config to specify path.\n"
54391
- );
54392
- process.exit(1);
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
- if (isMultiTeamConfig(config)) {
54395
- const teamEntries = getTeamEntries(config, opts.team);
54396
- for (const [teamId, teamConfig] of teamEntries) {
54397
- if (!opts.quiet) process.stdout.write(`
54398
- --- Team: ${teamId} ---
54399
- `);
54400
- const resolved2 = await resolve4(teamConfig.dsl);
54401
- const data2 = teamConfig.vars ? substituteVars(resolved2.data, teamConfig.vars) : resolved2.data;
54402
- const schemaResult2 = validateSchema(data2);
54403
- if (!schemaResult2.success) {
54404
- process.stderr.write(
54405
- `Schema validation failed for team ${teamId}. Run 'agent-contracts validate' for details.
54406
- `
54407
- );
54408
- process.exit(1);
54409
- }
54410
- let renderOptions2;
54411
- if (teamConfig.bindings.length > 0) {
54412
- const loadedBindings = await loadBindings(teamConfig.bindings);
54413
- renderOptions2 = {
54414
- loadedBindings,
54415
- activeGuardrailPolicy: teamConfig.activeGuardrailPolicy
54416
- };
54417
- }
54418
- if (opts.check) {
54419
- const drift = await checkDriftFromConfig(
54420
- schemaResult2.data,
54421
- config.renders,
54422
- renderOptions2
54423
- );
54424
- if (drift.hasDrift) {
54425
- process.stderr.write(
54426
- `Drift detected for team ${teamId} in the following files:
54427
- `
54428
- );
54429
- for (const f2 of drift.diffs) {
54430
- process.stderr.write(` ${f2}
54431
- `);
54432
- }
54433
- process.exit(1);
54434
- }
54435
- if (!opts.quiet) {
54436
- process.stdout.write("No drift detected.\n");
54437
- }
54438
- } else {
54439
- const files = await renderFromConfig(
54440
- schemaResult2.data,
54441
- config.renders,
54442
- renderOptions2
54443
- );
54444
- if (!opts.quiet) {
54445
- process.stdout.write(`Rendered ${files.length} file(s):
54446
- `);
54447
- for (const f2 of files) {
54448
- process.stdout.write(` ${f2}
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
- const resolved = await resolve4(config.dsl);
54457
- const data = config.vars ? substituteVars(resolved.data, config.vars) : resolved.data;
54458
- const schemaResult = validateSchema(data);
54459
- if (!schemaResult.success) {
54460
- process.stderr.write(
54461
- "Schema validation failed. Run 'agent-contracts validate' for details.\n"
54462
- );
54463
- process.exit(1);
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
- let renderOptions;
54466
- if (config.bindings.length > 0) {
54467
- const loadedBindings = await loadBindings(config.bindings);
54468
- renderOptions = {
54469
- loadedBindings,
54470
- activeGuardrailPolicy: config.activeGuardrailPolicy
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
- if (opts.check) {
54474
- const drift = await checkDriftFromConfig(
54475
- schemaResult.data,
54476
- config.renders,
54477
- renderOptions
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
- const files = await renderFromConfig(
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
- } catch (err) {
54506
- if (err instanceof ConfigLoadError) {
54507
- process.stderr.write(`Config error: ${err.message}
54508
- `);
54509
- process.exit(1);
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
- // src/cli/commands/check.ts
54520
- import { existsSync, readFileSync } from "fs";
54521
- import { join as join3 } from "path";
54522
- import { Command as Command5 } from "commander";
54523
- import { parse as parseYaml4, stringify as stringify3 } from "yaml";
54524
- import { access as access2 } from "fs/promises";
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
- if (ti.description !== void 0) {
54538
- doc.description = ti.description;
54539
- }
54540
- if (ti.accepts?.workflows && Object.keys(ti.accepts.workflows).length > 0) {
54541
- doc.accepts = { workflows: { ...ti.accepts.workflows } };
54542
- }
54543
- const handoffKeys = /* @__PURE__ */ new Set();
54544
- if (ti.accepts?.workflows) {
54545
- for (const spec of Object.values(ti.accepts.workflows)) {
54546
- handoffKeys.add(spec.input_handoff);
54547
- handoffKeys.add(spec.output_handoff);
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
- const handoff_types = {};
54551
- for (const k2 of [...handoffKeys].sort()) {
54552
- const ht = dsl.handoff_types[k2];
54553
- if (ht) {
54554
- const entry = {
54555
- version: ht.version,
54556
- schema: ht.schema
54557
- };
54558
- if (ht.description !== void 0) {
54559
- entry.description = ht.description;
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
- if (Object.keys(handoff_types).length > 0) {
54565
- doc.handoff_types = handoff_types;
54566
- }
54567
- const artifactsOut = {};
54568
- if (ti.exposes?.artifacts) {
54569
- for (const key of [...ti.exposes.artifacts].sort()) {
54570
- const art = dsl.artifacts[key];
54571
- if (art) {
54572
- const entry = {
54573
- type: art.type,
54574
- states: art.states
54575
- };
54576
- if (art.description !== void 0) {
54577
- entry.description = art.description;
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
- if (Object.keys(artifactsOut).length > 0) {
54584
- doc.exposes = { artifacts: artifactsOut };
54585
- }
54586
- if (ti.constraints !== void 0 && ti.constraints.length > 0) {
54587
- doc.constraints = ti.constraints;
54588
- }
54589
- return doc;
54590
- }
54591
- function generateInterface(options) {
54592
- if (!options.dsl.team_interface) {
54593
- throw new Error("DSL has no team_interface section");
54594
- }
54595
- const doc = buildInterfaceDocument(options.dsl, (/* @__PURE__ */ new Date()).toISOString());
54596
- const content = options.format === "json" ? `${JSON.stringify(doc, null, 2)}
54597
- ` : `${stringify2(doc, { sortMapEntries: true })}
54598
- `;
54599
- const outputPath = options.output ?? "team-interface.yaml";
54600
- return { outputPath, content };
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 dirname7 } from "path";
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(dirname7(targetPath), { recursive: true });
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(dirname7(groupTarget), { recursive: true });
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(dirname7(targetPath), { recursive: true });
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(dirname7(outputPath), { recursive: true });
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(dirname7(outputPath), { recursive: true });
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/cli/commands/generate-interface.ts
55270
- import { writeFileSync } from "fs";
55271
- import { resolve as resolve7 } from "path";
55272
- function runGenerateInterfaceCli(opts) {
55273
- if (!opts.dsl.team_interface) {
55274
- process.stderr.write("Error: DSL has no team_interface section.\n");
55275
- process.exit(1);
55276
- }
55277
- const outputPath = resolve7(process.cwd(), opts.output ?? "team-interface.yaml");
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
- var OPTIONAL_ENTITY_FIELDS = {
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
- return {
55638
- id: "schema-completeness",
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
- for (const [toolId, tool] of Object.entries(dsl.tools)) {
55681
- for (const agentId of tool.invokable_by) {
55682
- totalChecks++;
55683
- const agent = dsl.agents[agentId];
55684
- if (agent && agent.can_execute_tools.includes(toolId)) {
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
- return {
55692
- id: "cross-reference-bidirectionality",
55693
- label: "Cross-reference bidirectionality",
55694
- score: passedChecks,
55695
- total: totalChecks,
55696
- percent: pct(passedChecks, totalChecks),
55697
- weight: 2,
55698
- recommendations: issues.length > 0 ? [`${issues.length} unreciprocated cross-references: ${issues.slice(0, 5).join(", ")}${issues.length > 5 ? `, ... (${issues.length - 5} more)` : ""}`] : []
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
- let total = 0;
55723
- let covered = 0;
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
- return {
55738
- id: "entity-guardrail-coverage",
55739
- label: "Entity guardrail coverage",
55740
- score: covered,
55741
- total,
55742
- percent: pct(covered, total),
55743
- weight: 1,
55744
- recommendations: missing.length > 0 ? [`${missing.length} entities without guardrails: ${missing.slice(0, 5).join(", ")}${missing.length > 5 ? `, ... (${missing.length - 5} more)` : ""}`] : []
55745
- };
55746
- }
55747
- function guardrailScopeResolution(dsl) {
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
- return {
55775
- id: "guardrail-scope-resolution",
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
- const allRecs = result.dimensions.flatMap((d2) => d2.recommendations);
55817
- if (allRecs.length > 0) {
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 lines.join("\n");
55759
+ return doc;
55825
55760
  }
55826
- var scoreCommand = new Command7("score").description("Calculate DSL completeness score").argument("[dir]", "Path to agent-contracts.yaml", DIR_DEFAULT4).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("--threshold <number>", "Minimum score (exit 1 if below)", void 0).action(
55827
- async (dir, opts) => {
55828
- try {
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
- // src/cli/commands/audit.ts
55920
- import { writeFileSync as writeFileSync2 } from "fs";
55921
- import { Command as Command8 } from "commander";
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/commands/audit.ts
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(config) {
56679
- if (!config) return {};
56680
- const audit = config;
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, opts, failOn) {
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 (opts.adapter) auditConfig.adapter = opts.adapter;
56700
- if (opts.model) auditConfig.model = opts.model;
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: opts.format,
56704
- scope: opts.scope,
56705
- dryRun: opts.dryRun
57121
+ format: auditOpts.format,
57122
+ scope: auditOpts.scope,
57123
+ dryRun: auditOpts.dryRun
56706
57124
  });
56707
57125
  let output2;
56708
- if (opts.dryRun) {
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, opts.format) + "\n";
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: opts.format,
56723
- scope: opts.scope,
56724
- dryRun: opts.dryRun
57138
+ format: auditOpts.format,
57139
+ scope: auditOpts.scope,
57140
+ dryRun: auditOpts.dryRun
56725
57141
  });
56726
57142
  let output;
56727
- if (opts.dryRun) {
57143
+ if (auditOpts.dryRun) {
56728
57144
  output = result.prompt + "\n";
56729
57145
  } else {
56730
- output = formatAuditResult(result, opts.format) + "\n";
57146
+ output = formatAuditResult(result, auditOpts.format) + "\n";
56731
57147
  }
56732
57148
  return { exitCode: computeExitCode([result], failOn), output };
56733
57149
  }
56734
- var auditCommand = new Command8("audit").description("Run LLM-based semantic audit on DSL definitions and generated outputs").argument("[type]", `Audit type: ${AUDIT_TYPES.join(", ")}`, "all").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|markdown)", "text").option("--scope <entities>", "Limit audit scope (e.g. agents:architect,implementer)").option("--dry-run", "Output the audit prompt without calling LLM", false).option("--adapter <name>", "SDK adapter to use (default from config)").option("--model <name>", "LLM model override").option("--fail-on <level>", "Minimum 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 (for cli-contracts standard conformance)").action(
56735
- async (type, opts) => {
56736
- if (!AUDIT_TYPES.includes(type)) {
56737
- process.stderr.write(
56738
- `Unknown audit type: "${type}". Use one of: ${AUDIT_TYPES.join(", ")}
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
- const format2 = opts.reportFormat ?? opts.format;
56744
- try {
56745
- const config = await loadConfig(opts.config);
56746
- if (!config) {
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
- "Error: agent-contracts.config.yaml not found. Use --config to specify path.\n"
57261
+ `Schema validation failed${teamLabel ? ` for team ${teamLabel}` : ""}. Run 'agent-contracts validate' for details.
57262
+ `
56749
57263
  );
56750
- process.exit(1);
57264
+ return true;
56751
57265
  }
56752
- if (isMultiTeamConfig(config)) {
56753
- const teamEntries = getTeamEntries(config, opts.team);
56754
- let maxExit = 0;
56755
- const allOutput = [];
56756
- for (const [teamId, teamConfig] of teamEntries) {
56757
- process.stderr.write(`
56758
- --- Team: ${teamId} ---
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
- const result2 = await runAuditForDsl(
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
- process.exit(1);
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
- const msg = err instanceof Error ? err.message : String(err);
56793
- process.stderr.write(`Error: ${msg}
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 = new Command9();
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