agent-contracts 0.25.0 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -0
- package/cli-contract.yaml +176 -81
- package/dist/cli.js +1045 -174
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +81 -4
- package/dist/index.js +838 -118
- package/dist/index.js.map +1 -1
- package/docs/cli-reference.md +80 -30
- package/dsl_base/agents/dsl-auditor.yaml +5 -11
- package/dsl_base/agents/dsl-designer.yaml +7 -17
- package/dsl_base/artifacts.yaml +0 -28
- package/dsl_base/components.yaml +4 -4
- package/dsl_base/tasks.yaml +2 -0
- package/package.json +6 -3
package/dist/index.js
CHANGED
|
@@ -158,11 +158,11 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
158
158
|
}
|
|
159
159
|
function __awaiter(thisArg, _arguments, P2, generator) {
|
|
160
160
|
function adopt(value) {
|
|
161
|
-
return value instanceof P2 ? value : new P2(function(
|
|
162
|
-
|
|
161
|
+
return value instanceof P2 ? value : new P2(function(resolve8) {
|
|
162
|
+
resolve8(value);
|
|
163
163
|
});
|
|
164
164
|
}
|
|
165
|
-
return new (P2 || (P2 = Promise))(function(
|
|
165
|
+
return new (P2 || (P2 = Promise))(function(resolve8, reject) {
|
|
166
166
|
function fulfilled(value) {
|
|
167
167
|
try {
|
|
168
168
|
step(generator.next(value));
|
|
@@ -178,7 +178,7 @@ function __awaiter(thisArg, _arguments, P2, generator) {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
function step(result) {
|
|
181
|
-
result.done ?
|
|
181
|
+
result.done ? resolve8(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
182
182
|
}
|
|
183
183
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
184
184
|
});
|
|
@@ -369,14 +369,14 @@ function __asyncValues(o3) {
|
|
|
369
369
|
}, i3);
|
|
370
370
|
function verb(n3) {
|
|
371
371
|
i3[n3] = o3[n3] && function(v2) {
|
|
372
|
-
return new Promise(function(
|
|
373
|
-
v2 = o3[n3](v2), settle(
|
|
372
|
+
return new Promise(function(resolve8, reject) {
|
|
373
|
+
v2 = o3[n3](v2), settle(resolve8, reject, v2.done, v2.value);
|
|
374
374
|
});
|
|
375
375
|
};
|
|
376
376
|
}
|
|
377
|
-
function settle(
|
|
377
|
+
function settle(resolve8, reject, d2, v2) {
|
|
378
378
|
Promise.resolve(v2).then(function(v3) {
|
|
379
|
-
|
|
379
|
+
resolve8({ value: v3, done: d2 });
|
|
380
380
|
}, reject);
|
|
381
381
|
}
|
|
382
382
|
}
|
|
@@ -12936,13 +12936,13 @@ var require_yaml2 = __commonJS({
|
|
|
12936
12936
|
function getLocationForJsonPath(result, path) {
|
|
12937
12937
|
return (0, yaml_1.getLocationForJsonPath)(result, path);
|
|
12938
12938
|
}
|
|
12939
|
-
var
|
|
12939
|
+
var parseYaml5 = (input) => (0, yaml_1.parseWithPointers)(input, {
|
|
12940
12940
|
ignoreDuplicateKeys: false,
|
|
12941
12941
|
mergeKeys: true,
|
|
12942
12942
|
preserveKeyOrder: true,
|
|
12943
12943
|
attachComments: false
|
|
12944
12944
|
});
|
|
12945
|
-
exports.parseYaml =
|
|
12945
|
+
exports.parseYaml = parseYaml5;
|
|
12946
12946
|
exports.Yaml = {
|
|
12947
12947
|
parse: exports.parseYaml,
|
|
12948
12948
|
getLocationForJsonPath,
|
|
@@ -13032,11 +13032,11 @@ function __metadata2(metadataKey, metadataValue) {
|
|
|
13032
13032
|
}
|
|
13033
13033
|
function __awaiter2(thisArg, _arguments, P2, generator) {
|
|
13034
13034
|
function adopt(value) {
|
|
13035
|
-
return value instanceof P2 ? value : new P2(function(
|
|
13036
|
-
|
|
13035
|
+
return value instanceof P2 ? value : new P2(function(resolve8) {
|
|
13036
|
+
resolve8(value);
|
|
13037
13037
|
});
|
|
13038
13038
|
}
|
|
13039
|
-
return new (P2 || (P2 = Promise))(function(
|
|
13039
|
+
return new (P2 || (P2 = Promise))(function(resolve8, reject) {
|
|
13040
13040
|
function fulfilled(value) {
|
|
13041
13041
|
try {
|
|
13042
13042
|
step(generator.next(value));
|
|
@@ -13052,7 +13052,7 @@ function __awaiter2(thisArg, _arguments, P2, generator) {
|
|
|
13052
13052
|
}
|
|
13053
13053
|
}
|
|
13054
13054
|
function step(result) {
|
|
13055
|
-
result.done ?
|
|
13055
|
+
result.done ? resolve8(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
13056
13056
|
}
|
|
13057
13057
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13058
13058
|
});
|
|
@@ -13230,14 +13230,14 @@ function __asyncValues2(o3) {
|
|
|
13230
13230
|
}, i3);
|
|
13231
13231
|
function verb(n3) {
|
|
13232
13232
|
i3[n3] = o3[n3] && function(v2) {
|
|
13233
|
-
return new Promise(function(
|
|
13234
|
-
v2 = o3[n3](v2), settle(
|
|
13233
|
+
return new Promise(function(resolve8, reject) {
|
|
13234
|
+
v2 = o3[n3](v2), settle(resolve8, reject, v2.done, v2.value);
|
|
13235
13235
|
});
|
|
13236
13236
|
};
|
|
13237
13237
|
}
|
|
13238
|
-
function settle(
|
|
13238
|
+
function settle(resolve8, reject, d2, v2) {
|
|
13239
13239
|
Promise.resolve(v2).then(function(v3) {
|
|
13240
|
-
|
|
13240
|
+
resolve8({ value: v3, done: d2 });
|
|
13241
13241
|
}, reject);
|
|
13242
13242
|
}
|
|
13243
13243
|
}
|
|
@@ -18835,7 +18835,7 @@ function consumeBody() {
|
|
|
18835
18835
|
let accum = [];
|
|
18836
18836
|
let accumBytes = 0;
|
|
18837
18837
|
let abort = false;
|
|
18838
|
-
return new Body.Promise(function(
|
|
18838
|
+
return new Body.Promise(function(resolve8, reject) {
|
|
18839
18839
|
let resTimeout;
|
|
18840
18840
|
if (_this4.timeout) {
|
|
18841
18841
|
resTimeout = setTimeout(function() {
|
|
@@ -18869,7 +18869,7 @@ function consumeBody() {
|
|
|
18869
18869
|
}
|
|
18870
18870
|
clearTimeout(resTimeout);
|
|
18871
18871
|
try {
|
|
18872
|
-
|
|
18872
|
+
resolve8(Buffer.concat(accum, accumBytes));
|
|
18873
18873
|
} catch (err) {
|
|
18874
18874
|
reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, "system", err));
|
|
18875
18875
|
}
|
|
@@ -19132,7 +19132,7 @@ function fetch(url, opts) {
|
|
|
19132
19132
|
throw new Error("native promise missing, set fetch.Promise to your favorite alternative");
|
|
19133
19133
|
}
|
|
19134
19134
|
Body.Promise = fetch.Promise;
|
|
19135
|
-
return new fetch.Promise(function(
|
|
19135
|
+
return new fetch.Promise(function(resolve8, reject) {
|
|
19136
19136
|
const request = new Request(url, opts);
|
|
19137
19137
|
const options = getNodeRequestOptions(request);
|
|
19138
19138
|
const send = (options.protocol === "https:" ? https : http).request;
|
|
@@ -19265,7 +19265,7 @@ function fetch(url, opts) {
|
|
|
19265
19265
|
requestOpts.body = void 0;
|
|
19266
19266
|
requestOpts.headers.delete("content-length");
|
|
19267
19267
|
}
|
|
19268
|
-
|
|
19268
|
+
resolve8(fetch(new Request(locationURL, requestOpts)));
|
|
19269
19269
|
finalize();
|
|
19270
19270
|
return;
|
|
19271
19271
|
}
|
|
@@ -19286,7 +19286,7 @@ function fetch(url, opts) {
|
|
|
19286
19286
|
const codings = headers.get("Content-Encoding");
|
|
19287
19287
|
if (!request.compress || request.method === "HEAD" || codings === null || res.statusCode === 204 || res.statusCode === 304) {
|
|
19288
19288
|
response = new Response(body, response_options);
|
|
19289
|
-
|
|
19289
|
+
resolve8(response);
|
|
19290
19290
|
return;
|
|
19291
19291
|
}
|
|
19292
19292
|
const zlibOptions = {
|
|
@@ -19296,7 +19296,7 @@ function fetch(url, opts) {
|
|
|
19296
19296
|
if (codings == "gzip" || codings == "x-gzip") {
|
|
19297
19297
|
body = body.pipe(zlib.createGunzip(zlibOptions));
|
|
19298
19298
|
response = new Response(body, response_options);
|
|
19299
|
-
|
|
19299
|
+
resolve8(response);
|
|
19300
19300
|
return;
|
|
19301
19301
|
}
|
|
19302
19302
|
if (codings == "deflate" || codings == "x-deflate") {
|
|
@@ -19308,12 +19308,12 @@ function fetch(url, opts) {
|
|
|
19308
19308
|
body = body.pipe(zlib.createInflateRaw());
|
|
19309
19309
|
}
|
|
19310
19310
|
response = new Response(body, response_options);
|
|
19311
|
-
|
|
19311
|
+
resolve8(response);
|
|
19312
19312
|
});
|
|
19313
19313
|
raw.on("end", function() {
|
|
19314
19314
|
if (!response) {
|
|
19315
19315
|
response = new Response(body, response_options);
|
|
19316
|
-
|
|
19316
|
+
resolve8(response);
|
|
19317
19317
|
}
|
|
19318
19318
|
});
|
|
19319
19319
|
return;
|
|
@@ -19321,11 +19321,11 @@ function fetch(url, opts) {
|
|
|
19321
19321
|
if (codings == "br" && typeof zlib.createBrotliDecompress === "function") {
|
|
19322
19322
|
body = body.pipe(zlib.createBrotliDecompress());
|
|
19323
19323
|
response = new Response(body, response_options);
|
|
19324
|
-
|
|
19324
|
+
resolve8(response);
|
|
19325
19325
|
return;
|
|
19326
19326
|
}
|
|
19327
19327
|
response = new Response(body, response_options);
|
|
19328
|
-
|
|
19328
|
+
resolve8(response);
|
|
19329
19329
|
});
|
|
19330
19330
|
writeToStream(req, request);
|
|
19331
19331
|
});
|
|
@@ -20038,13 +20038,13 @@ var require_file = __commonJS({
|
|
|
20038
20038
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20039
20039
|
var fs_1 = __require("fs");
|
|
20040
20040
|
function resolveFile(ref) {
|
|
20041
|
-
return new Promise((
|
|
20041
|
+
return new Promise((resolve8, reject) => {
|
|
20042
20042
|
const path = ref.href();
|
|
20043
20043
|
fs_1.readFile(path, "utf8", (err, data) => {
|
|
20044
20044
|
if (err) {
|
|
20045
20045
|
reject(err);
|
|
20046
20046
|
} else {
|
|
20047
|
-
|
|
20047
|
+
resolve8(data);
|
|
20048
20048
|
}
|
|
20049
20049
|
});
|
|
20050
20050
|
});
|
|
@@ -27647,12 +27647,12 @@ var require_reader = __commonJS({
|
|
|
27647
27647
|
}
|
|
27648
27648
|
} else {
|
|
27649
27649
|
try {
|
|
27650
|
-
return await new Promise((
|
|
27650
|
+
return await new Promise((resolve8, reject) => {
|
|
27651
27651
|
fs.readFile(name, opts.encoding, (err, data) => {
|
|
27652
27652
|
if (err !== null) {
|
|
27653
27653
|
reject(err);
|
|
27654
27654
|
} else {
|
|
27655
|
-
|
|
27655
|
+
resolve8(data);
|
|
27656
27656
|
}
|
|
27657
27657
|
});
|
|
27658
27658
|
});
|
|
@@ -40341,17 +40341,19 @@ var require_errors = __commonJS({
|
|
|
40341
40341
|
exports.convertAjvErrors = exports.RulesetValidationError = void 0;
|
|
40342
40342
|
var isAggregateError_1 = require_isAggregateError();
|
|
40343
40343
|
var RulesetValidationError = class extends Error {
|
|
40344
|
-
constructor(code, message, path) {
|
|
40344
|
+
constructor(code, message, path, location2) {
|
|
40345
40345
|
super(message);
|
|
40346
40346
|
this.code = code;
|
|
40347
40347
|
this.message = message;
|
|
40348
40348
|
this.path = path;
|
|
40349
|
+
this.range = location2 === null || location2 === void 0 ? void 0 : location2.range;
|
|
40350
|
+
this.source = location2 === null || location2 === void 0 ? void 0 : location2.source;
|
|
40349
40351
|
}
|
|
40350
40352
|
};
|
|
40351
40353
|
exports.RulesetValidationError = RulesetValidationError;
|
|
40352
40354
|
var RULE_INSTANCE_PATH = /^\/rules\/[^/]+/;
|
|
40353
40355
|
var GENERIC_INSTANCE_PATH = /^\/(?:aliases|extends|overrides(?:\/\d+\/extends)?)/;
|
|
40354
|
-
function convertAjvErrors(errors) {
|
|
40356
|
+
function convertAjvErrors(errors, sourceContext) {
|
|
40355
40357
|
const sortedErrors = [...errors].sort((errorA, errorB) => {
|
|
40356
40358
|
const diff = errorA.instancePath.length - errorB.instancePath.length;
|
|
40357
40359
|
return diff === 0 ? errorA.keyword === "errorMessage" && errorB.keyword !== "errorMessage" ? -1 : 0 : diff;
|
|
@@ -40384,10 +40386,12 @@ var require_errors = __commonJS({
|
|
|
40384
40386
|
return filteredErrors.flatMap((error) => {
|
|
40385
40387
|
var _a;
|
|
40386
40388
|
if (error.keyword === "x-spectral-runtime") {
|
|
40387
|
-
|
|
40389
|
+
const flat = flatErrors(error.params.errors);
|
|
40390
|
+
const list = Array.isArray(flat) ? flat : [flat];
|
|
40391
|
+
return list.map((e3) => enrichWithLocation(e3, sourceContext));
|
|
40388
40392
|
}
|
|
40389
40393
|
const path = error.instancePath.slice(1).split("/");
|
|
40390
|
-
return new RulesetValidationError(inferErrorCode(path, error.keyword), (_a = error.message) !== null && _a !== void 0 ? _a : "unknown error", path);
|
|
40394
|
+
return new RulesetValidationError(inferErrorCode(path, error.keyword), (_a = error.message) !== null && _a !== void 0 ? _a : "unknown error", path, resolveLocation(path, sourceContext));
|
|
40391
40395
|
});
|
|
40392
40396
|
}
|
|
40393
40397
|
exports.convertAjvErrors = convertAjvErrors;
|
|
@@ -40397,6 +40401,22 @@ var require_errors = __commonJS({
|
|
|
40397
40401
|
}
|
|
40398
40402
|
return error;
|
|
40399
40403
|
}
|
|
40404
|
+
function resolveLocation(path, sourceContext) {
|
|
40405
|
+
var _a;
|
|
40406
|
+
if (sourceContext === void 0) {
|
|
40407
|
+
return void 0;
|
|
40408
|
+
}
|
|
40409
|
+
return {
|
|
40410
|
+
source: sourceContext.source,
|
|
40411
|
+
range: (_a = sourceContext.getLocationForJsonPath(path)) === null || _a === void 0 ? void 0 : _a.range
|
|
40412
|
+
};
|
|
40413
|
+
}
|
|
40414
|
+
function enrichWithLocation(error, sourceContext) {
|
|
40415
|
+
if (sourceContext === void 0 || error.source !== void 0 || error.range !== void 0) {
|
|
40416
|
+
return error;
|
|
40417
|
+
}
|
|
40418
|
+
return new RulesetValidationError(error.code, error.message, error.path, resolveLocation(error.path, sourceContext));
|
|
40419
|
+
}
|
|
40400
40420
|
function inferErrorCode(path, keyword) {
|
|
40401
40421
|
if (path.length === 0) {
|
|
40402
40422
|
return "generic-validation-error";
|
|
@@ -44537,14 +44557,14 @@ var require_AsyncFromSyncIteratorContinuation = __commonJS({
|
|
|
44537
44557
|
if (!$Promise) {
|
|
44538
44558
|
throw new $SyntaxError("This environment does not support Promises.");
|
|
44539
44559
|
}
|
|
44540
|
-
return new $Promise(function(
|
|
44560
|
+
return new $Promise(function(resolve8) {
|
|
44541
44561
|
var done = IteratorComplete(result);
|
|
44542
44562
|
var value = IteratorValue(result);
|
|
44543
44563
|
var valueWrapper = PromiseResolve($Promise, value);
|
|
44544
44564
|
var onFulfilled = function(value2) {
|
|
44545
44565
|
return CreateIteratorResultObject(value2, done);
|
|
44546
44566
|
};
|
|
44547
|
-
|
|
44567
|
+
resolve8($then(valueWrapper, onFulfilled));
|
|
44548
44568
|
});
|
|
44549
44569
|
};
|
|
44550
44570
|
}
|
|
@@ -45092,7 +45112,7 @@ var require_CreateAsyncFromSyncIterator = __commonJS({
|
|
|
45092
45112
|
var O2 = this;
|
|
45093
45113
|
SLOT.assert(O2, "[[SyncIteratorRecord]]");
|
|
45094
45114
|
var argsLength = arguments.length;
|
|
45095
|
-
return new $Promise(function(
|
|
45115
|
+
return new $Promise(function(resolve8) {
|
|
45096
45116
|
var syncIteratorRecord = SLOT.get(O2, "[[SyncIteratorRecord]]");
|
|
45097
45117
|
var result;
|
|
45098
45118
|
if (argsLength > 0) {
|
|
@@ -45100,7 +45120,7 @@ var require_CreateAsyncFromSyncIterator = __commonJS({
|
|
|
45100
45120
|
} else {
|
|
45101
45121
|
result = IteratorNext(syncIteratorRecord);
|
|
45102
45122
|
}
|
|
45103
|
-
|
|
45123
|
+
resolve8(AsyncFromSyncIteratorContinuation(result));
|
|
45104
45124
|
});
|
|
45105
45125
|
},
|
|
45106
45126
|
"return": function() {
|
|
@@ -45111,12 +45131,12 @@ var require_CreateAsyncFromSyncIterator = __commonJS({
|
|
|
45111
45131
|
SLOT.assert(O2, "[[SyncIteratorRecord]]");
|
|
45112
45132
|
var valueIsPresent = arguments.length > 0;
|
|
45113
45133
|
var value = valueIsPresent ? arguments[0] : void 0;
|
|
45114
|
-
return new $Promise(function(
|
|
45134
|
+
return new $Promise(function(resolve8, reject) {
|
|
45115
45135
|
var syncIterator = SLOT.get(O2, "[[SyncIteratorRecord]]")["[[Iterator]]"];
|
|
45116
45136
|
var iteratorReturn = GetMethod(syncIterator, "return");
|
|
45117
45137
|
if (typeof iteratorReturn === "undefined") {
|
|
45118
45138
|
var iterResult = CreateIteratorResultObject(value, true);
|
|
45119
|
-
Call(
|
|
45139
|
+
Call(resolve8, void 0, [iterResult]);
|
|
45120
45140
|
return;
|
|
45121
45141
|
}
|
|
45122
45142
|
var result;
|
|
@@ -45129,7 +45149,7 @@ var require_CreateAsyncFromSyncIterator = __commonJS({
|
|
|
45129
45149
|
Call(reject, void 0, [new $TypeError("Iterator `return` method returned a non-object value.")]);
|
|
45130
45150
|
return;
|
|
45131
45151
|
}
|
|
45132
|
-
|
|
45152
|
+
resolve8(AsyncFromSyncIteratorContinuation(result));
|
|
45133
45153
|
});
|
|
45134
45154
|
},
|
|
45135
45155
|
"throw": function() {
|
|
@@ -45140,7 +45160,7 @@ var require_CreateAsyncFromSyncIterator = __commonJS({
|
|
|
45140
45160
|
SLOT.assert(O2, "[[SyncIteratorRecord]]");
|
|
45141
45161
|
var valueIsPresent = arguments.length > 0;
|
|
45142
45162
|
var value = valueIsPresent ? arguments[0] : void 0;
|
|
45143
|
-
return new $Promise(function(
|
|
45163
|
+
return new $Promise(function(resolve8, reject) {
|
|
45144
45164
|
var syncIterator = SLOT.get(O2, "[[SyncIteratorRecord]]")["[[Iterator]]"];
|
|
45145
45165
|
var throwMethod = GetMethod(syncIterator, "throw");
|
|
45146
45166
|
if (typeof throwMethod === "undefined") {
|
|
@@ -45157,7 +45177,7 @@ var require_CreateAsyncFromSyncIterator = __commonJS({
|
|
|
45157
45177
|
Call(reject, void 0, [new $TypeError("Iterator `throw` method returned a non-object value.")]);
|
|
45158
45178
|
return;
|
|
45159
45179
|
}
|
|
45160
|
-
|
|
45180
|
+
resolve8(AsyncFromSyncIteratorContinuation(
|
|
45161
45181
|
result
|
|
45162
45182
|
/* , promiseCapability */
|
|
45163
45183
|
));
|
|
@@ -45917,17 +45937,17 @@ var require_assertions = __commonJS({
|
|
|
45917
45937
|
var ajv_1 = require_ajv();
|
|
45918
45938
|
var errors_1 = require_errors();
|
|
45919
45939
|
var es_aggregate_error_1 = (0, tslib_1.__importDefault)(require_es_aggregate_error());
|
|
45920
|
-
function assertValidRuleset(ruleset2, format2 = "js") {
|
|
45921
|
-
var _a;
|
|
45940
|
+
function assertValidRuleset(ruleset2, format2 = "js", sourceContext) {
|
|
45941
|
+
var _a, _b;
|
|
45922
45942
|
if (!(0, json_1.isPlainObject)(ruleset2)) {
|
|
45923
|
-
throw new errors_1.RulesetValidationError("invalid-ruleset-definition", "Provided ruleset is not an object", []);
|
|
45943
|
+
throw new errors_1.RulesetValidationError("invalid-ruleset-definition", "Provided ruleset is not an object", [], sourceContext === void 0 ? void 0 : { source: sourceContext.source });
|
|
45924
45944
|
}
|
|
45925
45945
|
if (!("rules" in ruleset2) && !("extends" in ruleset2) && !("overrides" in ruleset2)) {
|
|
45926
|
-
throw new errors_1.RulesetValidationError("invalid-ruleset-definition", "Ruleset must have rules or extends or overrides defined", []);
|
|
45946
|
+
throw new errors_1.RulesetValidationError("invalid-ruleset-definition", "Ruleset must have rules or extends or overrides defined", [], sourceContext === void 0 ? void 0 : { source: sourceContext.source, range: (_a = sourceContext.getLocationForJsonPath([])) === null || _a === void 0 ? void 0 : _a.range });
|
|
45927
45947
|
}
|
|
45928
45948
|
const validate = (0, ajv_1.createValidator)(format2);
|
|
45929
45949
|
if (!validate(ruleset2)) {
|
|
45930
|
-
throw new es_aggregate_error_1.default((0, errors_1.convertAjvErrors)((
|
|
45950
|
+
throw new es_aggregate_error_1.default((0, errors_1.convertAjvErrors)((_b = validate.errors) !== null && _b !== void 0 ? _b : [], sourceContext));
|
|
45931
45951
|
}
|
|
45932
45952
|
}
|
|
45933
45953
|
exports.assertValidRuleset = assertValidRuleset;
|
|
@@ -46097,10 +46117,10 @@ var require_ruleset = __commonJS({
|
|
|
46097
46117
|
let definition;
|
|
46098
46118
|
if ((0, json_1.isPlainObject)(maybeDefinition) && "extends" in maybeDefinition) {
|
|
46099
46119
|
const { extends: _2, ...def } = maybeDefinition;
|
|
46100
|
-
(0, index_1.assertValidRuleset)({ extends: [], ...def }, "js");
|
|
46120
|
+
(0, index_1.assertValidRuleset)({ extends: [], ...def }, "js", context === null || context === void 0 ? void 0 : context.sourceContext);
|
|
46101
46121
|
definition = maybeDefinition;
|
|
46102
46122
|
} else {
|
|
46103
|
-
(0, index_1.assertValidRuleset)(maybeDefinition, "js");
|
|
46123
|
+
(0, index_1.assertValidRuleset)(maybeDefinition, "js", context === null || context === void 0 ? void 0 : context.sourceContext);
|
|
46104
46124
|
definition = maybeDefinition;
|
|
46105
46125
|
}
|
|
46106
46126
|
this.definition = definition;
|
|
@@ -48975,11 +48995,12 @@ var CONTEXT_TYPES = [
|
|
|
48975
48995
|
"policy",
|
|
48976
48996
|
"guardrail",
|
|
48977
48997
|
"guardrail_policy",
|
|
48978
|
-
"system"
|
|
48998
|
+
"system",
|
|
48999
|
+
"navigation_index"
|
|
48979
49000
|
];
|
|
48980
49001
|
var ContextTypeSchema = z3.enum(CONTEXT_TYPES);
|
|
48981
49002
|
var ITERABLE_CONTEXT_TYPES = CONTEXT_TYPES.filter(
|
|
48982
|
-
(t3) => t3 !== "system"
|
|
49003
|
+
(t3) => t3 !== "system" && t3 !== "navigation_index"
|
|
48983
49004
|
);
|
|
48984
49005
|
|
|
48985
49006
|
// src/schema/binding.ts
|
|
@@ -49217,7 +49238,9 @@ var CommandSchema = z12.object({
|
|
|
49217
49238
|
purpose: z12.string().optional()
|
|
49218
49239
|
});
|
|
49219
49240
|
var ToolSchema = z12.object({
|
|
49220
|
-
kind: z12.string(),
|
|
49241
|
+
kind: z12.string().optional(),
|
|
49242
|
+
extends: z12.string().optional(),
|
|
49243
|
+
command: z12.string().optional(),
|
|
49221
49244
|
description: z12.string().optional(),
|
|
49222
49245
|
input_artifacts: z12.array(z12.string()).default([]),
|
|
49223
49246
|
output_artifacts: z12.array(z12.string()).default([]),
|
|
@@ -50166,6 +50189,123 @@ function mergeDsl(base, project) {
|
|
|
50166
50189
|
|
|
50167
50190
|
// src/resolver/resolve.ts
|
|
50168
50191
|
import { dirname as dirname2, resolve as resolvePath } from "path";
|
|
50192
|
+
|
|
50193
|
+
// src/resolver/tool-extends.ts
|
|
50194
|
+
var ToolExtendsError = class extends Error {
|
|
50195
|
+
constructor(message) {
|
|
50196
|
+
super(message);
|
|
50197
|
+
this.name = "ToolExtendsError";
|
|
50198
|
+
}
|
|
50199
|
+
};
|
|
50200
|
+
function asStringArray(value) {
|
|
50201
|
+
return Array.isArray(value) ? value : [];
|
|
50202
|
+
}
|
|
50203
|
+
function asRecord(value) {
|
|
50204
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
50205
|
+
return value;
|
|
50206
|
+
}
|
|
50207
|
+
return {};
|
|
50208
|
+
}
|
|
50209
|
+
function asCommands(value) {
|
|
50210
|
+
return Array.isArray(value) ? value : [];
|
|
50211
|
+
}
|
|
50212
|
+
function isUnset(value) {
|
|
50213
|
+
return value === void 0 || value === null;
|
|
50214
|
+
}
|
|
50215
|
+
function mergeToolFields(base, child) {
|
|
50216
|
+
const merged = { ...child };
|
|
50217
|
+
merged.artifact_bindings = {
|
|
50218
|
+
...asRecord(base.artifact_bindings),
|
|
50219
|
+
...asRecord(child.artifact_bindings)
|
|
50220
|
+
};
|
|
50221
|
+
if (isUnset(child.kind) && !isUnset(base.kind)) {
|
|
50222
|
+
merged.kind = base.kind;
|
|
50223
|
+
}
|
|
50224
|
+
if (isUnset(child.cli_contract) && !isUnset(base.cli_contract)) {
|
|
50225
|
+
merged.cli_contract = base.cli_contract;
|
|
50226
|
+
}
|
|
50227
|
+
if (isUnset(child.description) && !isUnset(base.description)) {
|
|
50228
|
+
merged.description = base.description;
|
|
50229
|
+
}
|
|
50230
|
+
const childInvokableBy = asStringArray(child.invokable_by);
|
|
50231
|
+
const baseInvokableBy = asStringArray(base.invokable_by);
|
|
50232
|
+
if (childInvokableBy.length === 0 && baseInvokableBy.length > 0) {
|
|
50233
|
+
merged.invokable_by = [...baseInvokableBy];
|
|
50234
|
+
}
|
|
50235
|
+
const childInputArtifacts = asStringArray(child.input_artifacts);
|
|
50236
|
+
const baseInputArtifacts = asStringArray(base.input_artifacts);
|
|
50237
|
+
if (childInputArtifacts.length === 0 && baseInputArtifacts.length > 0) {
|
|
50238
|
+
merged.input_artifacts = [...baseInputArtifacts];
|
|
50239
|
+
}
|
|
50240
|
+
const childOutputArtifacts = asStringArray(child.output_artifacts);
|
|
50241
|
+
const baseOutputArtifacts = asStringArray(base.output_artifacts);
|
|
50242
|
+
if (childOutputArtifacts.length === 0 && baseOutputArtifacts.length > 0) {
|
|
50243
|
+
merged.output_artifacts = [...baseOutputArtifacts];
|
|
50244
|
+
}
|
|
50245
|
+
const childSideEffects = asStringArray(child.side_effects);
|
|
50246
|
+
const baseSideEffects = asStringArray(base.side_effects);
|
|
50247
|
+
if (childSideEffects.length === 0 && baseSideEffects.length > 0) {
|
|
50248
|
+
merged.side_effects = [...baseSideEffects];
|
|
50249
|
+
}
|
|
50250
|
+
const childCommands = asCommands(child.commands);
|
|
50251
|
+
const baseCommands = asCommands(base.commands);
|
|
50252
|
+
if (childCommands.length === 0 && baseCommands.length > 0) {
|
|
50253
|
+
merged.commands = [...baseCommands];
|
|
50254
|
+
}
|
|
50255
|
+
if (isUnset(child.guardrails) && !isUnset(base.guardrails)) {
|
|
50256
|
+
merged.guardrails = base.guardrails;
|
|
50257
|
+
}
|
|
50258
|
+
return merged;
|
|
50259
|
+
}
|
|
50260
|
+
function resolveToolChain(id, tools, resolving, resolved) {
|
|
50261
|
+
const cached = resolved.get(id);
|
|
50262
|
+
if (cached !== void 0) {
|
|
50263
|
+
return cached;
|
|
50264
|
+
}
|
|
50265
|
+
const tool = tools[id];
|
|
50266
|
+
if (tool === void 0) {
|
|
50267
|
+
throw new ToolExtendsError(`Tool "${id}" not found`);
|
|
50268
|
+
}
|
|
50269
|
+
const extendsId = tool.extends;
|
|
50270
|
+
if (extendsId === void 0) {
|
|
50271
|
+
resolved.set(id, tool);
|
|
50272
|
+
return tool;
|
|
50273
|
+
}
|
|
50274
|
+
if (resolving.has(id)) {
|
|
50275
|
+
throw new ToolExtendsError(
|
|
50276
|
+
`Circular tool extends detected involving "${id}"`
|
|
50277
|
+
);
|
|
50278
|
+
}
|
|
50279
|
+
const baseTool = tools[extendsId];
|
|
50280
|
+
if (baseTool === void 0) {
|
|
50281
|
+
resolved.set(id, tool);
|
|
50282
|
+
return tool;
|
|
50283
|
+
}
|
|
50284
|
+
resolving.add(id);
|
|
50285
|
+
try {
|
|
50286
|
+
const resolvedBase = resolveToolChain(
|
|
50287
|
+
extendsId,
|
|
50288
|
+
tools,
|
|
50289
|
+
resolving,
|
|
50290
|
+
resolved
|
|
50291
|
+
);
|
|
50292
|
+
const merged = mergeToolFields(resolvedBase, tool);
|
|
50293
|
+
resolved.set(id, merged);
|
|
50294
|
+
return merged;
|
|
50295
|
+
} finally {
|
|
50296
|
+
resolving.delete(id);
|
|
50297
|
+
}
|
|
50298
|
+
}
|
|
50299
|
+
function resolveToolExtends(tools) {
|
|
50300
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
50301
|
+
const result = {};
|
|
50302
|
+
for (const id of Object.keys(tools)) {
|
|
50303
|
+
result[id] = resolveToolChain(id, tools, /* @__PURE__ */ new Set(), resolved);
|
|
50304
|
+
}
|
|
50305
|
+
return result;
|
|
50306
|
+
}
|
|
50307
|
+
|
|
50308
|
+
// src/resolver/resolve.ts
|
|
50169
50309
|
async function resolveExtendsChain(data, filePath, seen) {
|
|
50170
50310
|
const extendsValue = data["extends"];
|
|
50171
50311
|
if (typeof extendsValue !== "string") {
|
|
@@ -50195,6 +50335,10 @@ async function resolve3(projectDirOrFile) {
|
|
|
50195
50335
|
projectResult.filePath,
|
|
50196
50336
|
/* @__PURE__ */ new Set()
|
|
50197
50337
|
);
|
|
50338
|
+
const tools = data["tools"];
|
|
50339
|
+
if (tools !== void 0 && tools !== null && typeof tools === "object" && !Array.isArray(tools)) {
|
|
50340
|
+
data["tools"] = resolveToolExtends(tools);
|
|
50341
|
+
}
|
|
50198
50342
|
return {
|
|
50199
50343
|
data,
|
|
50200
50344
|
projectPath: projectResult.filePath,
|
|
@@ -51012,7 +51156,7 @@ function checkReferences(dsl) {
|
|
|
51012
51156
|
for (const [id, art] of Object.entries(dsl.artifacts)) {
|
|
51013
51157
|
if (art.owner) {
|
|
51014
51158
|
const ownerAgent = dsl.agents[art.owner];
|
|
51015
|
-
if (ownerAgent && !ownerAgent.can_read_artifacts.includes(id)) {
|
|
51159
|
+
if (ownerAgent && ownerAgent.can_read_artifacts.length > 0 && !ownerAgent.can_read_artifacts.includes(id)) {
|
|
51016
51160
|
diagnostics.push({
|
|
51017
51161
|
path: `artifacts.${id}.owner`,
|
|
51018
51162
|
message: `Agent "${art.owner}" owns artifact "${id}" but cannot read it (missing from can_read_artifacts)`,
|
|
@@ -51035,6 +51179,15 @@ function checkReferences(dsl) {
|
|
|
51035
51179
|
}
|
|
51036
51180
|
}
|
|
51037
51181
|
for (const [id, tool] of Object.entries(dsl.tools)) {
|
|
51182
|
+
if (tool.extends) {
|
|
51183
|
+
checkExists(
|
|
51184
|
+
tool.extends,
|
|
51185
|
+
toolIds,
|
|
51186
|
+
"tools",
|
|
51187
|
+
`tools.${id}.extends`,
|
|
51188
|
+
"tool-extends-not-found"
|
|
51189
|
+
);
|
|
51190
|
+
}
|
|
51038
51191
|
if (tool.invokable_by.length > 0) {
|
|
51039
51192
|
for (const ref of tool.invokable_by) {
|
|
51040
51193
|
checkExists(ref, agentIds, "agents", `tools.${id}.invokable_by`);
|
|
@@ -51117,14 +51270,16 @@ function checkReferences(dsl) {
|
|
|
51117
51270
|
code: "result-handoff-not-returnable"
|
|
51118
51271
|
});
|
|
51119
51272
|
}
|
|
51120
|
-
|
|
51121
|
-
|
|
51122
|
-
|
|
51123
|
-
|
|
51124
|
-
|
|
51125
|
-
|
|
51126
|
-
|
|
51127
|
-
|
|
51273
|
+
if (targetAgent.can_read_artifacts.length > 0) {
|
|
51274
|
+
for (let j2 = 0; j2 < task.input_artifacts.length; j2++) {
|
|
51275
|
+
const inputId = task.input_artifacts[j2];
|
|
51276
|
+
if (!targetAgent.can_read_artifacts.includes(inputId)) {
|
|
51277
|
+
diagnostics.push({
|
|
51278
|
+
path: `tasks.${id}.input_artifacts[${j2}]`,
|
|
51279
|
+
message: `Input artifact "${inputId}" is not in target agent "${task.target_agent}" can_read_artifacts`,
|
|
51280
|
+
code: "input-artifact-not-readable"
|
|
51281
|
+
});
|
|
51282
|
+
}
|
|
51128
51283
|
}
|
|
51129
51284
|
}
|
|
51130
51285
|
}
|
|
@@ -51140,7 +51295,7 @@ function checkReferences(dsl) {
|
|
|
51140
51295
|
if (agent.prerequisites) {
|
|
51141
51296
|
for (let j2 = 0; j2 < agent.prerequisites.length; j2++) {
|
|
51142
51297
|
const pre = agent.prerequisites[j2];
|
|
51143
|
-
if (!agent.can_read_artifacts.includes(pre.target)) {
|
|
51298
|
+
if (agent.can_read_artifacts.length > 0 && !agent.can_read_artifacts.includes(pre.target)) {
|
|
51144
51299
|
diagnostics.push({
|
|
51145
51300
|
path: `agents.${id}.prerequisites[${j2}].target`,
|
|
51146
51301
|
message: `Prerequisite target "${pre.target}" is not in agent "${id}" can_read_artifacts`,
|
|
@@ -51531,14 +51686,16 @@ var taskAgentBindingRule = {
|
|
|
51531
51686
|
for (const [taskId, task] of Object.entries(dsl.tasks)) {
|
|
51532
51687
|
const targetAgent = dsl.agents[task.target_agent];
|
|
51533
51688
|
if (!targetAgent) continue;
|
|
51534
|
-
|
|
51535
|
-
|
|
51536
|
-
|
|
51537
|
-
|
|
51538
|
-
|
|
51539
|
-
|
|
51540
|
-
|
|
51541
|
-
|
|
51689
|
+
if (targetAgent.can_read_artifacts.length > 0) {
|
|
51690
|
+
for (const ref of task.input_artifacts) {
|
|
51691
|
+
if (!targetAgent.can_read_artifacts.includes(ref)) {
|
|
51692
|
+
diagnostics.push({
|
|
51693
|
+
ruleId: "task-agent-binding",
|
|
51694
|
+
severity: "error",
|
|
51695
|
+
path: `tasks.${taskId}.input_artifacts`,
|
|
51696
|
+
message: `Task "${taskId}" input_artifact "${ref}" not in target agent "${task.target_agent}" can_read_artifacts`
|
|
51697
|
+
});
|
|
51698
|
+
}
|
|
51542
51699
|
}
|
|
51543
51700
|
}
|
|
51544
51701
|
if (!targetAgent.can_return_handoffs.includes(task.result_handoff)) {
|
|
@@ -51574,7 +51731,7 @@ var taskAgentBindingRule = {
|
|
|
51574
51731
|
});
|
|
51575
51732
|
}
|
|
51576
51733
|
}
|
|
51577
|
-
if (step.produces_artifact) {
|
|
51734
|
+
if (step.produces_artifact && targetAgent.can_write_artifacts.length > 0) {
|
|
51578
51735
|
if (!targetAgent.can_write_artifacts.includes(step.produces_artifact)) {
|
|
51579
51736
|
diagnostics.push({
|
|
51580
51737
|
ruleId: "task-agent-binding",
|
|
@@ -51584,7 +51741,7 @@ var taskAgentBindingRule = {
|
|
|
51584
51741
|
});
|
|
51585
51742
|
}
|
|
51586
51743
|
}
|
|
51587
|
-
if (step.reads_artifact) {
|
|
51744
|
+
if (step.reads_artifact && targetAgent.can_read_artifacts.length > 0) {
|
|
51588
51745
|
if (!targetAgent.can_read_artifacts.includes(step.reads_artifact)) {
|
|
51589
51746
|
diagnostics.push({
|
|
51590
51747
|
ruleId: "task-agent-binding",
|
|
@@ -51649,7 +51806,8 @@ var artifactOwnershipRule = {
|
|
|
51649
51806
|
}
|
|
51650
51807
|
if (step.reads_artifact) {
|
|
51651
51808
|
const artifact = dsl.artifacts[step.reads_artifact];
|
|
51652
|
-
|
|
51809
|
+
const hasDeprecatedOwnership = !!artifact?.owner || (artifact?.producers.length ?? 0) > 0 || (artifact?.editors.length ?? 0) > 0 || (artifact?.consumers.length ?? 0) > 0;
|
|
51810
|
+
if (artifact && hasDeprecatedOwnership) {
|
|
51653
51811
|
const canRead = artifact.consumers.includes(agentId) || artifact.producers.includes(agentId) || artifact.editors.includes(agentId);
|
|
51654
51812
|
if (!canRead) {
|
|
51655
51813
|
diagnostics.push({
|
|
@@ -52087,6 +52245,7 @@ var artifactOwnershipConsistencyRule = {
|
|
|
52087
52245
|
run(dsl) {
|
|
52088
52246
|
const diagnostics = [];
|
|
52089
52247
|
for (const [agentId, agent] of Object.entries(dsl.agents)) {
|
|
52248
|
+
if (agent.own_artifacts.length === 0) continue;
|
|
52090
52249
|
for (const artId of agent.own_artifacts) {
|
|
52091
52250
|
if (!agent.can_read_artifacts.includes(artId)) {
|
|
52092
52251
|
diagnostics.push({
|
|
@@ -52114,6 +52273,68 @@ var artifactOwnershipConsistencyRule = {
|
|
|
52114
52273
|
}
|
|
52115
52274
|
};
|
|
52116
52275
|
|
|
52276
|
+
// src/linter/rules/deprecated-ownership-fields.ts
|
|
52277
|
+
var ARTIFACT_FIELDS = ["owner", "producers", "editors", "consumers"];
|
|
52278
|
+
var AGENT_FIELDS = [
|
|
52279
|
+
"own_artifacts",
|
|
52280
|
+
"can_read_artifacts",
|
|
52281
|
+
"can_write_artifacts"
|
|
52282
|
+
];
|
|
52283
|
+
function isArtifactFieldUsed(artifact, field) {
|
|
52284
|
+
switch (field) {
|
|
52285
|
+
case "owner":
|
|
52286
|
+
return !!artifact.owner;
|
|
52287
|
+
case "producers":
|
|
52288
|
+
return artifact.producers.length > 0;
|
|
52289
|
+
case "editors":
|
|
52290
|
+
return artifact.editors.length > 0;
|
|
52291
|
+
case "consumers":
|
|
52292
|
+
return artifact.consumers.length > 0;
|
|
52293
|
+
}
|
|
52294
|
+
}
|
|
52295
|
+
function isAgentFieldUsed(agent, field) {
|
|
52296
|
+
switch (field) {
|
|
52297
|
+
case "own_artifacts":
|
|
52298
|
+
return agent.own_artifacts.length > 0;
|
|
52299
|
+
case "can_read_artifacts":
|
|
52300
|
+
return agent.can_read_artifacts.length > 0;
|
|
52301
|
+
case "can_write_artifacts":
|
|
52302
|
+
return agent.can_write_artifacts.length > 0;
|
|
52303
|
+
}
|
|
52304
|
+
}
|
|
52305
|
+
var deprecatedOwnershipFieldsRule = {
|
|
52306
|
+
id: "deprecated-ownership-fields",
|
|
52307
|
+
description: "Warn when deprecated ownership/permission fields are used instead of artifact_bindings + artifact_slots",
|
|
52308
|
+
run(dsl) {
|
|
52309
|
+
const diagnostics = [];
|
|
52310
|
+
for (const [artId, artifact] of Object.entries(dsl.artifacts)) {
|
|
52311
|
+
for (const field of ARTIFACT_FIELDS) {
|
|
52312
|
+
if (isArtifactFieldUsed(artifact, field)) {
|
|
52313
|
+
diagnostics.push({
|
|
52314
|
+
ruleId: "deprecated-ownership-fields",
|
|
52315
|
+
severity: "warning",
|
|
52316
|
+
path: `artifacts.${artId}.${field}`,
|
|
52317
|
+
message: `Artifact "${artId}" uses deprecated field "${field}". Ownership is derived from artifact_bindings + artifact_slots in the binding model.`
|
|
52318
|
+
});
|
|
52319
|
+
}
|
|
52320
|
+
}
|
|
52321
|
+
}
|
|
52322
|
+
for (const [agentId, agent] of Object.entries(dsl.agents)) {
|
|
52323
|
+
for (const field of AGENT_FIELDS) {
|
|
52324
|
+
if (isAgentFieldUsed(agent, field)) {
|
|
52325
|
+
diagnostics.push({
|
|
52326
|
+
ruleId: "deprecated-ownership-fields",
|
|
52327
|
+
severity: "warning",
|
|
52328
|
+
path: `agents.${agentId}.${field}`,
|
|
52329
|
+
message: `Agent "${agentId}" uses deprecated field "${field}". Artifact permissions are derived from artifact_bindings + artifact_slots in the binding model.`
|
|
52330
|
+
});
|
|
52331
|
+
}
|
|
52332
|
+
}
|
|
52333
|
+
}
|
|
52334
|
+
return diagnostics;
|
|
52335
|
+
}
|
|
52336
|
+
};
|
|
52337
|
+
|
|
52117
52338
|
// src/linter/rules/extension-consumption.ts
|
|
52118
52339
|
function isRecord4(v2) {
|
|
52119
52340
|
return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
|
|
@@ -52284,6 +52505,194 @@ var extensionUndeclaredUsageRule = {
|
|
|
52284
52505
|
}
|
|
52285
52506
|
};
|
|
52286
52507
|
|
|
52508
|
+
// src/navigation-index/cli-contract-loader.ts
|
|
52509
|
+
import { existsSync, readFileSync } from "fs";
|
|
52510
|
+
import { isAbsolute, resolve as resolve4 } from "path";
|
|
52511
|
+
import { parse as parseYaml2 } from "yaml";
|
|
52512
|
+
function extractStringArray(value) {
|
|
52513
|
+
if (!Array.isArray(value)) return [];
|
|
52514
|
+
return value.filter((item) => typeof item === "string");
|
|
52515
|
+
}
|
|
52516
|
+
function extractArtifactSlots(doc) {
|
|
52517
|
+
const slots = doc.artifact_slots;
|
|
52518
|
+
if (!slots || typeof slots !== "object") return null;
|
|
52519
|
+
const result = {};
|
|
52520
|
+
for (const [name, slotDef] of Object.entries(slots)) {
|
|
52521
|
+
if (!slotDef || typeof slotDef !== "object") continue;
|
|
52522
|
+
const direction = slotDef.direction;
|
|
52523
|
+
if (direction === "read" || direction === "write" || direction === "readwrite") {
|
|
52524
|
+
result[name] = { direction };
|
|
52525
|
+
}
|
|
52526
|
+
}
|
|
52527
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
52528
|
+
}
|
|
52529
|
+
function extractCommandEffects(doc) {
|
|
52530
|
+
const result = {};
|
|
52531
|
+
const commandSets = doc.command_sets;
|
|
52532
|
+
if (!commandSets || typeof commandSets !== "object") return result;
|
|
52533
|
+
for (const setDef of Object.values(commandSets)) {
|
|
52534
|
+
if (!setDef || typeof setDef !== "object") continue;
|
|
52535
|
+
const commands = setDef.commands;
|
|
52536
|
+
if (!commands || typeof commands !== "object") continue;
|
|
52537
|
+
for (const [cmdName, cmdDef] of Object.entries(commands)) {
|
|
52538
|
+
if (!cmdDef || typeof cmdDef !== "object") continue;
|
|
52539
|
+
const effects = cmdDef.effects;
|
|
52540
|
+
if (!effects || typeof effects !== "object") continue;
|
|
52541
|
+
result[cmdName] = {
|
|
52542
|
+
reads: extractStringArray(effects.reads),
|
|
52543
|
+
writes: extractStringArray(effects.writes)
|
|
52544
|
+
};
|
|
52545
|
+
}
|
|
52546
|
+
}
|
|
52547
|
+
return result;
|
|
52548
|
+
}
|
|
52549
|
+
function resolveCliContractPath(cliContractPath) {
|
|
52550
|
+
return isAbsolute(cliContractPath) ? cliContractPath : resolve4(process.cwd(), cliContractPath);
|
|
52551
|
+
}
|
|
52552
|
+
function loadCliContractSlots(cliContractPath) {
|
|
52553
|
+
const filePath = resolveCliContractPath(cliContractPath);
|
|
52554
|
+
if (!existsSync(filePath)) return null;
|
|
52555
|
+
let doc;
|
|
52556
|
+
try {
|
|
52557
|
+
doc = parseYaml2(readFileSync(filePath, "utf8"));
|
|
52558
|
+
} catch {
|
|
52559
|
+
return null;
|
|
52560
|
+
}
|
|
52561
|
+
if (!doc || typeof doc !== "object") return null;
|
|
52562
|
+
const artifactSlots = extractArtifactSlots(doc);
|
|
52563
|
+
if (!artifactSlots) return null;
|
|
52564
|
+
return {
|
|
52565
|
+
artifactSlots,
|
|
52566
|
+
commandEffects: extractCommandEffects(doc)
|
|
52567
|
+
};
|
|
52568
|
+
}
|
|
52569
|
+
function resolveSlotDirection(slot, command, slotInfo) {
|
|
52570
|
+
const cmdEffects = slotInfo.commandEffects[command];
|
|
52571
|
+
if (cmdEffects) {
|
|
52572
|
+
if (cmdEffects.writes.includes(slot)) return "write";
|
|
52573
|
+
if (cmdEffects.reads.includes(slot)) return "read";
|
|
52574
|
+
}
|
|
52575
|
+
const slotDecl = slotInfo.artifactSlots[slot];
|
|
52576
|
+
if (slotDecl) {
|
|
52577
|
+
if (slotDecl.direction === "write" || slotDecl.direction === "readwrite") {
|
|
52578
|
+
return "write";
|
|
52579
|
+
}
|
|
52580
|
+
return "read";
|
|
52581
|
+
}
|
|
52582
|
+
return "read";
|
|
52583
|
+
}
|
|
52584
|
+
|
|
52585
|
+
// src/linter/rules/binding-completeness.ts
|
|
52586
|
+
var bindingCompletenessRule = {
|
|
52587
|
+
id: "binding-completeness",
|
|
52588
|
+
description: "Check that artifact_bindings cover all slots referenced in the cli-contract command effects",
|
|
52589
|
+
run(dsl) {
|
|
52590
|
+
const diagnostics = [];
|
|
52591
|
+
for (const [toolId, tool] of Object.entries(dsl.tools)) {
|
|
52592
|
+
if (!tool.cli_contract || !tool.artifact_bindings) continue;
|
|
52593
|
+
const slotInfo = loadCliContractSlots(tool.cli_contract);
|
|
52594
|
+
if (!slotInfo?.artifactSlots) continue;
|
|
52595
|
+
const command = tool.command ?? "";
|
|
52596
|
+
const effects = slotInfo.commandEffects[command];
|
|
52597
|
+
if (!effects) continue;
|
|
52598
|
+
const referencedSlots = [...effects.reads, ...effects.writes];
|
|
52599
|
+
const boundSlots = new Set(Object.keys(tool.artifact_bindings));
|
|
52600
|
+
for (const slot of referencedSlots) {
|
|
52601
|
+
if (boundSlots.has(slot)) continue;
|
|
52602
|
+
diagnostics.push({
|
|
52603
|
+
ruleId: "binding-completeness",
|
|
52604
|
+
severity: "warning",
|
|
52605
|
+
path: `tools.${toolId}.artifact_bindings`,
|
|
52606
|
+
message: `Command "${command}" references slot "${slot}" but tool has no artifact_bindings entry for it`
|
|
52607
|
+
});
|
|
52608
|
+
}
|
|
52609
|
+
}
|
|
52610
|
+
return diagnostics;
|
|
52611
|
+
}
|
|
52612
|
+
};
|
|
52613
|
+
|
|
52614
|
+
// src/linter/rules/binding-direction-match.ts
|
|
52615
|
+
function agentCanWriteArtifact(agentId, artifactId, dsl) {
|
|
52616
|
+
const agent = dsl.agents[agentId];
|
|
52617
|
+
if (!agent) return false;
|
|
52618
|
+
return agent.can_write_artifacts.includes(artifactId) || agent.own_artifacts.includes(artifactId);
|
|
52619
|
+
}
|
|
52620
|
+
var bindingDirectionMatchRule = {
|
|
52621
|
+
id: "binding-direction-match",
|
|
52622
|
+
description: "Check that agents invoking a tool can write artifacts bound via write slots",
|
|
52623
|
+
run(dsl) {
|
|
52624
|
+
const diagnostics = [];
|
|
52625
|
+
for (const [toolId, tool] of Object.entries(dsl.tools)) {
|
|
52626
|
+
if (!tool.cli_contract || !tool.artifact_bindings) continue;
|
|
52627
|
+
const slotInfo = loadCliContractSlots(tool.cli_contract);
|
|
52628
|
+
if (!slotInfo) continue;
|
|
52629
|
+
const command = tool.command ?? "";
|
|
52630
|
+
for (const [slot, artifactId] of Object.entries(tool.artifact_bindings)) {
|
|
52631
|
+
const direction = resolveSlotDirection(slot, command, slotInfo);
|
|
52632
|
+
if (direction !== "write") continue;
|
|
52633
|
+
for (const agentId of tool.invokable_by) {
|
|
52634
|
+
if (agentCanWriteArtifact(agentId, artifactId, dsl)) continue;
|
|
52635
|
+
diagnostics.push({
|
|
52636
|
+
ruleId: "binding-direction-match",
|
|
52637
|
+
severity: "warning",
|
|
52638
|
+
path: `tools.${toolId}.artifact_bindings.${slot}`,
|
|
52639
|
+
message: `Agent "${agentId}" invokes tool "${toolId}" which writes to artifact "${artifactId}" via slot "${slot}", but agent lacks can_write_artifacts or own_artifacts for it`
|
|
52640
|
+
});
|
|
52641
|
+
}
|
|
52642
|
+
}
|
|
52643
|
+
}
|
|
52644
|
+
return diagnostics;
|
|
52645
|
+
}
|
|
52646
|
+
};
|
|
52647
|
+
|
|
52648
|
+
// src/linter/rules/slot-declaration-exists.ts
|
|
52649
|
+
var slotDeclarationExistsRule = {
|
|
52650
|
+
id: "slot-declaration-exists",
|
|
52651
|
+
description: "Check that artifact_bindings keys reference slot names declared in the cli-contract",
|
|
52652
|
+
run(dsl) {
|
|
52653
|
+
const diagnostics = [];
|
|
52654
|
+
for (const [toolId, tool] of Object.entries(dsl.tools)) {
|
|
52655
|
+
if (!tool.cli_contract || !tool.artifact_bindings) continue;
|
|
52656
|
+
const slotInfo = loadCliContractSlots(tool.cli_contract);
|
|
52657
|
+
if (!slotInfo?.artifactSlots) continue;
|
|
52658
|
+
for (const slot of Object.keys(tool.artifact_bindings)) {
|
|
52659
|
+
if (slot in slotInfo.artifactSlots) continue;
|
|
52660
|
+
diagnostics.push({
|
|
52661
|
+
ruleId: "slot-declaration-exists",
|
|
52662
|
+
severity: "warning",
|
|
52663
|
+
path: `tools.${toolId}.artifact_bindings.${slot}`,
|
|
52664
|
+
message: `artifact_bindings key "${slot}" is not declared in cli-contract artifactSlots`
|
|
52665
|
+
});
|
|
52666
|
+
}
|
|
52667
|
+
}
|
|
52668
|
+
return diagnostics;
|
|
52669
|
+
}
|
|
52670
|
+
};
|
|
52671
|
+
|
|
52672
|
+
// src/linter/rules/config-path-consistency.ts
|
|
52673
|
+
var configPathConsistencyRule = {
|
|
52674
|
+
id: "config-path-consistency",
|
|
52675
|
+
description: "Check that control-authority artifacts bound by tools have path_patterns defined",
|
|
52676
|
+
run(dsl) {
|
|
52677
|
+
const diagnostics = [];
|
|
52678
|
+
for (const [toolId, tool] of Object.entries(dsl.tools)) {
|
|
52679
|
+
if (!tool.artifact_bindings) continue;
|
|
52680
|
+
for (const [slot, artifactId] of Object.entries(tool.artifact_bindings)) {
|
|
52681
|
+
const artifact = dsl.artifacts[artifactId];
|
|
52682
|
+
if (!artifact || artifact.authority !== "control") continue;
|
|
52683
|
+
if (artifact.path_patterns && artifact.path_patterns.length > 0) continue;
|
|
52684
|
+
diagnostics.push({
|
|
52685
|
+
ruleId: "config-path-consistency",
|
|
52686
|
+
severity: "info",
|
|
52687
|
+
path: `tools.${toolId}.artifact_bindings.${slot}`,
|
|
52688
|
+
message: `Config artifact "${artifactId}" has no path_patterns; consider adding them for path-based lookup`
|
|
52689
|
+
});
|
|
52690
|
+
}
|
|
52691
|
+
}
|
|
52692
|
+
return diagnostics;
|
|
52693
|
+
}
|
|
52694
|
+
};
|
|
52695
|
+
|
|
52287
52696
|
// src/linter/linter.ts
|
|
52288
52697
|
var builtinRules = [
|
|
52289
52698
|
validationCoverageRule,
|
|
@@ -52302,9 +52711,14 @@ var builtinRules = [
|
|
|
52302
52711
|
guardrailOrphanedRule,
|
|
52303
52712
|
validationExecutorNoContextRule,
|
|
52304
52713
|
artifactOwnershipConsistencyRule,
|
|
52714
|
+
deprecatedOwnershipFieldsRule,
|
|
52305
52715
|
extensionDeclaredButUnusedRule,
|
|
52306
52716
|
extensionScopeMismatchRule,
|
|
52307
|
-
extensionUndeclaredUsageRule
|
|
52717
|
+
extensionUndeclaredUsageRule,
|
|
52718
|
+
bindingCompletenessRule,
|
|
52719
|
+
bindingDirectionMatchRule,
|
|
52720
|
+
slotDeclarationExistsRule,
|
|
52721
|
+
configPathConsistencyRule
|
|
52308
52722
|
];
|
|
52309
52723
|
function lint(dsl, rules = builtinRules) {
|
|
52310
52724
|
const diagnostics = [];
|
|
@@ -52358,9 +52772,18 @@ var ref_exists_default = (0, import_spectral_core.createRulesetFunction)(
|
|
|
52358
52772
|
|
|
52359
52773
|
// src/linter/spectral/functions/editors-not-empty.ts
|
|
52360
52774
|
var import_spectral_core2 = __toESM(require_dist9(), 1);
|
|
52775
|
+
function allDeprecatedOwnershipFieldsEmpty(art) {
|
|
52776
|
+
return !art.owner && (art.producers?.length ?? 0) === 0 && (art.editors?.length ?? 0) === 0 && (art.consumers?.length ?? 0) === 0;
|
|
52777
|
+
}
|
|
52361
52778
|
var editors_not_empty_default = (0, import_spectral_core2.createRulesetFunction)(
|
|
52362
52779
|
{ input: { type: "array" }, options: null },
|
|
52363
|
-
(targetVal, _options,
|
|
52780
|
+
(targetVal, _options, context) => {
|
|
52781
|
+
const root = context.document.data;
|
|
52782
|
+
const artId = context.path.length >= 2 ? String(context.path[1]) : void 0;
|
|
52783
|
+
const artifact = artId && root.artifacts ? root.artifacts[artId] : void 0;
|
|
52784
|
+
if (artifact && allDeprecatedOwnershipFieldsEmpty(artifact)) {
|
|
52785
|
+
return [];
|
|
52786
|
+
}
|
|
52364
52787
|
if (targetVal.length === 0) {
|
|
52365
52788
|
return [{ message: "editors must not be empty" }];
|
|
52366
52789
|
}
|
|
@@ -52392,6 +52815,7 @@ var prerequisite_readable_default = (0, import_spectral_core4.createRulesetFunct
|
|
|
52392
52815
|
(targetVal, _options, context) => {
|
|
52393
52816
|
const readable = new Set(targetVal.can_read_artifacts ?? []);
|
|
52394
52817
|
const prereqs = targetVal.prerequisites ?? [];
|
|
52818
|
+
if (readable.size === 0) return [];
|
|
52395
52819
|
const results = [];
|
|
52396
52820
|
for (let i3 = 0; i3 < prereqs.length; i3++) {
|
|
52397
52821
|
const p2 = prereqs[i3];
|
|
@@ -52793,7 +53217,7 @@ var ruleset = {
|
|
|
52793
53217
|
},
|
|
52794
53218
|
"artifact-owner-exists": {
|
|
52795
53219
|
description: "(deprecated) Every artifact must have an owner",
|
|
52796
|
-
severity: "
|
|
53220
|
+
severity: "off",
|
|
52797
53221
|
given: "$.artifacts.*",
|
|
52798
53222
|
then: {
|
|
52799
53223
|
field: "owner",
|
|
@@ -53667,7 +54091,7 @@ function emitExecutionStep(es, agentAlias2, participants, lines, indent) {
|
|
|
53667
54091
|
}
|
|
53668
54092
|
function emitValidationStep(step, participants, dsl, lastFromAgent, lines, indent) {
|
|
53669
54093
|
const val = dsl.validations[step.validation];
|
|
53670
|
-
if (!val) return;
|
|
54094
|
+
if (!val || !val.executor) return;
|
|
53671
54095
|
const executorAlias = participantAlias(participants, val.executor);
|
|
53672
54096
|
const artifactAlias = participantAlias(participants, val.target_artifact);
|
|
53673
54097
|
const fromAlias = lastFromAgent ? participantAlias(participants, lastFromAgent) : null;
|
|
@@ -53970,6 +54394,299 @@ function generateOverviewFlowchart(dsl) {
|
|
|
53970
54394
|
return sections.join("\n\n");
|
|
53971
54395
|
}
|
|
53972
54396
|
|
|
54397
|
+
// src/navigation-index/builder.ts
|
|
54398
|
+
var VALIDATOR_KINDS = /* @__PURE__ */ new Set(["linter", "checker", "validator", "test"]);
|
|
54399
|
+
var VALIDATION_TERMS = ["lint", "check", "validate", "test", "verify", "audit"];
|
|
54400
|
+
function sortUnique(values) {
|
|
54401
|
+
return [...new Set(values)].sort();
|
|
54402
|
+
}
|
|
54403
|
+
function matchesValidationTerm(value) {
|
|
54404
|
+
const lower = value.toLowerCase();
|
|
54405
|
+
return VALIDATION_TERMS.some((term) => lower.includes(term));
|
|
54406
|
+
}
|
|
54407
|
+
function isValidatorTool(tool) {
|
|
54408
|
+
if (tool.kind && VALIDATOR_KINDS.has(tool.kind)) {
|
|
54409
|
+
return true;
|
|
54410
|
+
}
|
|
54411
|
+
if (tool.command && matchesValidationTerm(tool.command)) {
|
|
54412
|
+
return true;
|
|
54413
|
+
}
|
|
54414
|
+
for (const cmd of tool.commands ?? []) {
|
|
54415
|
+
if (matchesValidationTerm(cmd.category) || matchesValidationTerm(cmd.command)) {
|
|
54416
|
+
return true;
|
|
54417
|
+
}
|
|
54418
|
+
}
|
|
54419
|
+
return false;
|
|
54420
|
+
}
|
|
54421
|
+
function extractToolArtifactLinks(toolId, tool) {
|
|
54422
|
+
const links = [];
|
|
54423
|
+
if (tool.cli_contract) {
|
|
54424
|
+
const command = tool.command ?? "";
|
|
54425
|
+
const slotInfo = loadCliContractSlots(tool.cli_contract);
|
|
54426
|
+
for (const [slot, artifactId] of Object.entries(tool.artifact_bindings ?? {})) {
|
|
54427
|
+
const direction = slotInfo ? resolveSlotDirection(slot, command, slotInfo) : "read";
|
|
54428
|
+
links.push({
|
|
54429
|
+
toolId,
|
|
54430
|
+
artifactId,
|
|
54431
|
+
direction,
|
|
54432
|
+
slot,
|
|
54433
|
+
command
|
|
54434
|
+
});
|
|
54435
|
+
}
|
|
54436
|
+
return links;
|
|
54437
|
+
}
|
|
54438
|
+
for (const cmd of tool.commands ?? []) {
|
|
54439
|
+
for (const artifactId of cmd.reads ?? []) {
|
|
54440
|
+
links.push({
|
|
54441
|
+
toolId,
|
|
54442
|
+
artifactId,
|
|
54443
|
+
direction: "read",
|
|
54444
|
+
slot: "",
|
|
54445
|
+
command: cmd.command
|
|
54446
|
+
});
|
|
54447
|
+
}
|
|
54448
|
+
for (const artifactId of cmd.writes ?? []) {
|
|
54449
|
+
links.push({
|
|
54450
|
+
toolId,
|
|
54451
|
+
artifactId,
|
|
54452
|
+
direction: "write",
|
|
54453
|
+
slot: "",
|
|
54454
|
+
command: cmd.command
|
|
54455
|
+
});
|
|
54456
|
+
}
|
|
54457
|
+
}
|
|
54458
|
+
return links;
|
|
54459
|
+
}
|
|
54460
|
+
function buildOperation(toolId, tool, link) {
|
|
54461
|
+
return {
|
|
54462
|
+
tool: toolId,
|
|
54463
|
+
cli_contract: tool.cli_contract ?? "",
|
|
54464
|
+
command: link.command || tool.command || "",
|
|
54465
|
+
slot: link.slot,
|
|
54466
|
+
invokable_by: [...tool.invokable_by ?? []]
|
|
54467
|
+
};
|
|
54468
|
+
}
|
|
54469
|
+
function operationKey(op) {
|
|
54470
|
+
return `${op.tool}:${op.command}:${op.slot}`;
|
|
54471
|
+
}
|
|
54472
|
+
function dedupeOperations(operations) {
|
|
54473
|
+
const seen = /* @__PURE__ */ new Set();
|
|
54474
|
+
const result = [];
|
|
54475
|
+
for (const op of operations) {
|
|
54476
|
+
const key = operationKey(op);
|
|
54477
|
+
if (seen.has(key)) continue;
|
|
54478
|
+
seen.add(key);
|
|
54479
|
+
result.push(op);
|
|
54480
|
+
}
|
|
54481
|
+
return result.sort((a3, b3) => a3.tool.localeCompare(b3.tool) || a3.slot.localeCompare(b3.slot));
|
|
54482
|
+
}
|
|
54483
|
+
function buildAgentMapping(dsl, artifactId) {
|
|
54484
|
+
const owners = [];
|
|
54485
|
+
const editors = [];
|
|
54486
|
+
const readers = [];
|
|
54487
|
+
for (const [agentId, agent] of Object.entries(dsl.agents)) {
|
|
54488
|
+
if (agent.own_artifacts?.includes(artifactId)) owners.push(agentId);
|
|
54489
|
+
if (agent.can_write_artifacts?.includes(artifactId)) editors.push(agentId);
|
|
54490
|
+
if (agent.can_read_artifacts?.includes(artifactId)) readers.push(agentId);
|
|
54491
|
+
}
|
|
54492
|
+
return {
|
|
54493
|
+
owners: sortUnique(owners),
|
|
54494
|
+
editors: sortUnique(editors),
|
|
54495
|
+
readers: sortUnique(readers)
|
|
54496
|
+
};
|
|
54497
|
+
}
|
|
54498
|
+
function buildRelations(artifactId, authority, linksByArtifact, allLinks) {
|
|
54499
|
+
const sourceArtifacts = /* @__PURE__ */ new Set();
|
|
54500
|
+
const derivedArtifacts = /* @__PURE__ */ new Set();
|
|
54501
|
+
const writesToThis = allLinks.filter(
|
|
54502
|
+
(link) => link.artifactId === artifactId && link.direction === "write"
|
|
54503
|
+
);
|
|
54504
|
+
if (authority === "generated" || authority === "derived") {
|
|
54505
|
+
for (const writeLink of writesToThis) {
|
|
54506
|
+
for (const readLink of allLinks) {
|
|
54507
|
+
if (readLink.toolId === writeLink.toolId && readLink.direction === "read") {
|
|
54508
|
+
sourceArtifacts.add(readLink.artifactId);
|
|
54509
|
+
}
|
|
54510
|
+
}
|
|
54511
|
+
}
|
|
54512
|
+
}
|
|
54513
|
+
const readsThis = allLinks.filter(
|
|
54514
|
+
(link) => link.artifactId === artifactId && link.direction === "read"
|
|
54515
|
+
);
|
|
54516
|
+
for (const readLink of readsThis) {
|
|
54517
|
+
for (const writeLink of allLinks) {
|
|
54518
|
+
if (writeLink.toolId === readLink.toolId && writeLink.direction === "write") {
|
|
54519
|
+
derivedArtifacts.add(writeLink.artifactId);
|
|
54520
|
+
}
|
|
54521
|
+
}
|
|
54522
|
+
}
|
|
54523
|
+
const knownArtifacts = new Set(linksByArtifact.keys());
|
|
54524
|
+
return {
|
|
54525
|
+
source_artifacts: sortUnique(
|
|
54526
|
+
[...sourceArtifacts].filter((id) => id !== artifactId && knownArtifacts.has(id))
|
|
54527
|
+
),
|
|
54528
|
+
derived_artifacts: sortUnique(
|
|
54529
|
+
[...derivedArtifacts].filter((id) => id !== artifactId && knownArtifacts.has(id))
|
|
54530
|
+
)
|
|
54531
|
+
};
|
|
54532
|
+
}
|
|
54533
|
+
function buildValidateRoutes(validators) {
|
|
54534
|
+
return validators.map((validator) => ({
|
|
54535
|
+
purpose: "validate",
|
|
54536
|
+
steps: [
|
|
54537
|
+
{
|
|
54538
|
+
type: "run_operation",
|
|
54539
|
+
operation: validator.tool,
|
|
54540
|
+
candidate_agents: [...validator.invokable_by]
|
|
54541
|
+
}
|
|
54542
|
+
]
|
|
54543
|
+
}));
|
|
54544
|
+
}
|
|
54545
|
+
function buildRegenerateRoutes(sourceArtifacts, producers, agentsByArtifact) {
|
|
54546
|
+
if (producers.length === 0) return [];
|
|
54547
|
+
const editSteps = sourceArtifacts.map((artifactId) => ({
|
|
54548
|
+
type: "edit_artifact",
|
|
54549
|
+
artifact: artifactId,
|
|
54550
|
+
candidate_agents: agentsByArtifact.get(artifactId)?.editors ?? []
|
|
54551
|
+
}));
|
|
54552
|
+
const runSteps = producers.map((producer) => ({
|
|
54553
|
+
type: "run_operation",
|
|
54554
|
+
operation: producer.tool,
|
|
54555
|
+
candidate_agents: [...producer.invokable_by]
|
|
54556
|
+
}));
|
|
54557
|
+
return [
|
|
54558
|
+
{
|
|
54559
|
+
purpose: "regenerate",
|
|
54560
|
+
steps: [...editSteps, ...runSteps]
|
|
54561
|
+
}
|
|
54562
|
+
];
|
|
54563
|
+
}
|
|
54564
|
+
function buildUpdateRoutes(artifactId, validators, editors) {
|
|
54565
|
+
const steps = [
|
|
54566
|
+
{
|
|
54567
|
+
type: "edit_artifact",
|
|
54568
|
+
artifact: artifactId,
|
|
54569
|
+
candidate_agents: [...editors]
|
|
54570
|
+
}
|
|
54571
|
+
];
|
|
54572
|
+
for (const validator of validators) {
|
|
54573
|
+
steps.push({
|
|
54574
|
+
type: "run_operation",
|
|
54575
|
+
operation: validator.tool,
|
|
54576
|
+
candidate_agents: [...validator.invokable_by]
|
|
54577
|
+
});
|
|
54578
|
+
}
|
|
54579
|
+
return [
|
|
54580
|
+
{
|
|
54581
|
+
purpose: "update",
|
|
54582
|
+
steps
|
|
54583
|
+
}
|
|
54584
|
+
];
|
|
54585
|
+
}
|
|
54586
|
+
function defaultProperties(artifact) {
|
|
54587
|
+
return {
|
|
54588
|
+
type: artifact.type,
|
|
54589
|
+
authority: artifact.authority ?? "canonical",
|
|
54590
|
+
manual_edit: artifact.manual_edit ?? "allowed",
|
|
54591
|
+
change_control: artifact.change_control ?? "none"
|
|
54592
|
+
};
|
|
54593
|
+
}
|
|
54594
|
+
function buildNavigationIndex(dsl) {
|
|
54595
|
+
const resolvedTools = resolveToolExtends(dsl.tools);
|
|
54596
|
+
const allLinks = [];
|
|
54597
|
+
for (const [toolId, tool] of Object.entries(resolvedTools)) {
|
|
54598
|
+
allLinks.push(...extractToolArtifactLinks(toolId, tool));
|
|
54599
|
+
}
|
|
54600
|
+
const linksByArtifact = /* @__PURE__ */ new Map();
|
|
54601
|
+
for (const link of allLinks) {
|
|
54602
|
+
const existing = linksByArtifact.get(link.artifactId) ?? [];
|
|
54603
|
+
existing.push(link);
|
|
54604
|
+
linksByArtifact.set(link.artifactId, existing);
|
|
54605
|
+
}
|
|
54606
|
+
const toolWrites = /* @__PURE__ */ new Map();
|
|
54607
|
+
for (const link of allLinks) {
|
|
54608
|
+
if (link.direction !== "write") continue;
|
|
54609
|
+
const writes = toolWrites.get(link.toolId) ?? /* @__PURE__ */ new Set();
|
|
54610
|
+
writes.add(link.artifactId);
|
|
54611
|
+
toolWrites.set(link.toolId, writes);
|
|
54612
|
+
}
|
|
54613
|
+
const artifacts = {};
|
|
54614
|
+
const agentsByArtifact = /* @__PURE__ */ new Map();
|
|
54615
|
+
for (const [artifactId, artifactDef] of Object.entries(dsl.artifacts)) {
|
|
54616
|
+
const properties = defaultProperties(artifactDef);
|
|
54617
|
+
const agents = buildAgentMapping(dsl, artifactId);
|
|
54618
|
+
agentsByArtifact.set(artifactId, agents);
|
|
54619
|
+
const artifactLinks = linksByArtifact.get(artifactId) ?? [];
|
|
54620
|
+
const producers = [];
|
|
54621
|
+
const validators = [];
|
|
54622
|
+
const consumers = [];
|
|
54623
|
+
const processedPairs = /* @__PURE__ */ new Set();
|
|
54624
|
+
for (const link of artifactLinks) {
|
|
54625
|
+
const tool = resolvedTools[link.toolId];
|
|
54626
|
+
if (!tool) continue;
|
|
54627
|
+
const pairKey = `${link.toolId}:${link.direction}:${link.slot}:${link.command}`;
|
|
54628
|
+
if (processedPairs.has(pairKey)) continue;
|
|
54629
|
+
processedPairs.add(pairKey);
|
|
54630
|
+
const operation = buildOperation(link.toolId, tool, link);
|
|
54631
|
+
const toolWritesArtifacts = toolWrites.get(link.toolId) ?? /* @__PURE__ */ new Set();
|
|
54632
|
+
if (link.direction === "write" || toolWritesArtifacts.has(artifactId)) {
|
|
54633
|
+
producers.push(operation);
|
|
54634
|
+
} else if (isValidatorTool(tool)) {
|
|
54635
|
+
validators.push(operation);
|
|
54636
|
+
} else if (link.direction === "read") {
|
|
54637
|
+
consumers.push(operation);
|
|
54638
|
+
}
|
|
54639
|
+
}
|
|
54640
|
+
const relations = buildRelations(
|
|
54641
|
+
artifactId,
|
|
54642
|
+
properties.authority,
|
|
54643
|
+
linksByArtifact,
|
|
54644
|
+
allLinks
|
|
54645
|
+
);
|
|
54646
|
+
const routes = {};
|
|
54647
|
+
const dedupedValidators = dedupeOperations(validators);
|
|
54648
|
+
const dedupedProducers = dedupeOperations(producers);
|
|
54649
|
+
if (dedupedValidators.length > 0) {
|
|
54650
|
+
routes.validate = buildValidateRoutes(dedupedValidators);
|
|
54651
|
+
}
|
|
54652
|
+
if (properties.authority === "generated" && dedupedProducers.length > 0 && relations.source_artifacts.length > 0) {
|
|
54653
|
+
routes.regenerate = buildRegenerateRoutes(
|
|
54654
|
+
relations.source_artifacts,
|
|
54655
|
+
dedupedProducers,
|
|
54656
|
+
agentsByArtifact
|
|
54657
|
+
);
|
|
54658
|
+
}
|
|
54659
|
+
if (properties.authority === "canonical") {
|
|
54660
|
+
routes.update = buildUpdateRoutes(artifactId, dedupedValidators, agents.editors);
|
|
54661
|
+
}
|
|
54662
|
+
artifacts[artifactId] = {
|
|
54663
|
+
id: artifactId,
|
|
54664
|
+
files: {
|
|
54665
|
+
path_patterns: artifactDef.path_patterns ?? [],
|
|
54666
|
+
exclude_patterns: artifactDef.exclude_patterns ?? []
|
|
54667
|
+
},
|
|
54668
|
+
properties,
|
|
54669
|
+
relations,
|
|
54670
|
+
operations: {
|
|
54671
|
+
producers: dedupeOperations(producers),
|
|
54672
|
+
validators: dedupedValidators,
|
|
54673
|
+
consumers: dedupeOperations(consumers)
|
|
54674
|
+
},
|
|
54675
|
+
agents,
|
|
54676
|
+
routes
|
|
54677
|
+
};
|
|
54678
|
+
}
|
|
54679
|
+
return {
|
|
54680
|
+
version: "1.0.0",
|
|
54681
|
+
generated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
54682
|
+
system: {
|
|
54683
|
+
id: dsl.system.id,
|
|
54684
|
+
name: dsl.system.name
|
|
54685
|
+
},
|
|
54686
|
+
artifacts
|
|
54687
|
+
};
|
|
54688
|
+
}
|
|
54689
|
+
|
|
53973
54690
|
// src/renderer/renderer.ts
|
|
53974
54691
|
Handlebars.registerHelper("eq", (a3, b3) => a3 === b3);
|
|
53975
54692
|
Handlebars.registerHelper("notEmpty", (obj) => {
|
|
@@ -54279,6 +54996,8 @@ function buildEntityContext(dsl, context, entityId) {
|
|
|
54279
54996
|
return buildGuardrailPolicyContext(dsl, entityId);
|
|
54280
54997
|
case "system":
|
|
54281
54998
|
return buildSystemContext(dsl);
|
|
54999
|
+
case "navigation_index":
|
|
55000
|
+
return buildNavigationIndex(dsl);
|
|
54282
55001
|
}
|
|
54283
55002
|
}
|
|
54284
55003
|
async function loadTemplate(templatePath) {
|
|
@@ -54298,8 +55017,8 @@ async function renderFromConfig(dsl, renderTargets, options) {
|
|
|
54298
55017
|
for (const target of renderTargets) {
|
|
54299
55018
|
const templateContent = await loadTemplate(target.template);
|
|
54300
55019
|
const compiled = Handlebars.compile(templateContent, { noEscape: false });
|
|
54301
|
-
if (target.context === "system") {
|
|
54302
|
-
const ctx = buildSystemContext(dsl, options);
|
|
55020
|
+
if (target.context === "system" || target.context === "navigation_index") {
|
|
55021
|
+
const ctx = target.context === "system" ? buildSystemContext(dsl, options) : buildNavigationIndex(dsl);
|
|
54303
55022
|
const output = compiled(ctx);
|
|
54304
55023
|
if (target.skip_empty && isEffectivelyEmpty(output)) {
|
|
54305
55024
|
await removeIfExists(target.output);
|
|
@@ -54355,8 +55074,8 @@ async function checkDriftFromConfig(dsl, renderTargets, options) {
|
|
|
54355
55074
|
for (const target of renderTargets) {
|
|
54356
55075
|
const templateContent = await loadTemplate(target.template);
|
|
54357
55076
|
const compiled = Handlebars.compile(templateContent, { noEscape: false });
|
|
54358
|
-
if (target.context === "system") {
|
|
54359
|
-
const ctx = buildSystemContext(dsl, options);
|
|
55077
|
+
if (target.context === "system" || target.context === "navigation_index") {
|
|
55078
|
+
const ctx = target.context === "system" ? buildSystemContext(dsl, options) : buildNavigationIndex(dsl);
|
|
54360
55079
|
const expected = compiled(ctx);
|
|
54361
55080
|
await checkExpectedVsExisting(expected, target.output, target.skip_empty, diffs);
|
|
54362
55081
|
} else {
|
|
@@ -54378,14 +55097,14 @@ async function checkDriftFromConfig(dsl, renderTargets, options) {
|
|
|
54378
55097
|
|
|
54379
55098
|
// src/config/binding-loader.ts
|
|
54380
55099
|
import { readFile as readFile4 } from "fs/promises";
|
|
54381
|
-
import { dirname as dirname5, resolve as
|
|
55100
|
+
import { dirname as dirname5, resolve as resolve6 } from "path";
|
|
54382
55101
|
import { stat as stat2 } from "fs/promises";
|
|
54383
|
-
import { parse as
|
|
55102
|
+
import { parse as parseYaml4 } from "yaml";
|
|
54384
55103
|
|
|
54385
55104
|
// src/config/loader.ts
|
|
54386
55105
|
import { readFile as readFile3, access } from "fs/promises";
|
|
54387
|
-
import { resolve as
|
|
54388
|
-
import { parse as
|
|
55106
|
+
import { resolve as resolve5, dirname as dirname4 } from "path";
|
|
55107
|
+
import { parse as parseYaml3 } from "yaml";
|
|
54389
55108
|
|
|
54390
55109
|
// src/config/types.ts
|
|
54391
55110
|
import { z as z19 } from "zod";
|
|
@@ -54486,24 +55205,24 @@ function resolveTeamConfigs(teams, configDir) {
|
|
|
54486
55205
|
for (const [key, team] of Object.entries(teams)) {
|
|
54487
55206
|
if (key === "_defaults") continue;
|
|
54488
55207
|
const mergedBindings = [...defaults?.bindings ?? [], ...team.bindings].map(
|
|
54489
|
-
(b3) =>
|
|
55208
|
+
(b3) => resolve5(configDir, b3)
|
|
54490
55209
|
);
|
|
54491
55210
|
const mergedVars = defaults?.vars || team.vars ? { ...defaults?.vars ?? {}, ...team.vars ?? {} } : void 0;
|
|
54492
55211
|
const mergedPaths = defaults?.paths || team.paths ? { ...defaults?.paths ?? {}, ...team.paths ?? {} } : void 0;
|
|
54493
55212
|
result[key] = {
|
|
54494
|
-
dsl:
|
|
55213
|
+
dsl: resolve5(configDir, team.dsl),
|
|
54495
55214
|
bindings: mergedBindings,
|
|
54496
55215
|
vars: mergedVars,
|
|
54497
55216
|
activeGuardrailPolicy: team.active_guardrail_policy ?? defaults?.active_guardrail_policy,
|
|
54498
55217
|
paths: mergedPaths,
|
|
54499
|
-
interfaceOutput: team.interface_output ?
|
|
55218
|
+
interfaceOutput: team.interface_output ? resolve5(configDir, team.interface_output) : void 0
|
|
54500
55219
|
};
|
|
54501
55220
|
}
|
|
54502
55221
|
return result;
|
|
54503
55222
|
}
|
|
54504
55223
|
async function loadConfig(configPath) {
|
|
54505
55224
|
const isExplicit = configPath !== void 0;
|
|
54506
|
-
const targetPath =
|
|
55225
|
+
const targetPath = resolve5(configPath ?? DEFAULT_CONFIG_NAME);
|
|
54507
55226
|
if (!await fileExists2(targetPath)) {
|
|
54508
55227
|
if (isExplicit) {
|
|
54509
55228
|
throw new ConfigLoadError(
|
|
@@ -54524,7 +55243,7 @@ async function loadConfig(configPath) {
|
|
|
54524
55243
|
}
|
|
54525
55244
|
let raw;
|
|
54526
55245
|
try {
|
|
54527
|
-
raw =
|
|
55246
|
+
raw = parseYaml3(content);
|
|
54528
55247
|
} catch (err) {
|
|
54529
55248
|
const msg = err instanceof Error ? err.message : String(err);
|
|
54530
55249
|
throw new ConfigLoadError(
|
|
@@ -54545,8 +55264,8 @@ ${issues}`,
|
|
|
54545
55264
|
const config = result.data;
|
|
54546
55265
|
const renders = config.renders.map((r3) => ({
|
|
54547
55266
|
...r3,
|
|
54548
|
-
template:
|
|
54549
|
-
output:
|
|
55267
|
+
template: resolve5(configDir, r3.template),
|
|
55268
|
+
output: resolve5(configDir, r3.output)
|
|
54550
55269
|
}));
|
|
54551
55270
|
if (config.teams) {
|
|
54552
55271
|
return {
|
|
@@ -54562,11 +55281,11 @@ ${issues}`,
|
|
|
54562
55281
|
};
|
|
54563
55282
|
}
|
|
54564
55283
|
return {
|
|
54565
|
-
dsl:
|
|
55284
|
+
dsl: resolve5(configDir, config.dsl),
|
|
54566
55285
|
vars: config.vars,
|
|
54567
55286
|
renders,
|
|
54568
55287
|
configDir,
|
|
54569
|
-
bindings: (config.bindings ?? []).map((b3) =>
|
|
55288
|
+
bindings: (config.bindings ?? []).map((b3) => resolve5(configDir, b3)),
|
|
54570
55289
|
activeGuardrailPolicy: config.active_guardrail_policy,
|
|
54571
55290
|
paths: config.paths,
|
|
54572
55291
|
audit: config.audit ?? void 0
|
|
@@ -54574,12 +55293,12 @@ ${issues}`,
|
|
|
54574
55293
|
}
|
|
54575
55294
|
function resolveDslPath(dirArg, dirArgDefault, config) {
|
|
54576
55295
|
if (dirArg !== void 0 && dirArg !== dirArgDefault) {
|
|
54577
|
-
return
|
|
55296
|
+
return resolve5(dirArg);
|
|
54578
55297
|
}
|
|
54579
55298
|
if (config) {
|
|
54580
55299
|
return config.dsl;
|
|
54581
55300
|
}
|
|
54582
|
-
return
|
|
55301
|
+
return resolve5(dirArgDefault);
|
|
54583
55302
|
}
|
|
54584
55303
|
|
|
54585
55304
|
// src/config/binding-merger.ts
|
|
@@ -54618,7 +55337,7 @@ async function loadRawBinding(filePath) {
|
|
|
54618
55337
|
);
|
|
54619
55338
|
}
|
|
54620
55339
|
try {
|
|
54621
|
-
return
|
|
55340
|
+
return parseYaml4(content);
|
|
54622
55341
|
} catch (err) {
|
|
54623
55342
|
const msg = err instanceof Error ? err.message : String(err);
|
|
54624
55343
|
throw new ConfigLoadError(
|
|
@@ -54635,7 +55354,7 @@ async function resolveBindingExtends(raw, filePath, seen) {
|
|
|
54635
55354
|
const bindingDir = dirname5(filePath);
|
|
54636
55355
|
let basePath;
|
|
54637
55356
|
if (extendsValue.startsWith("./") || extendsValue.startsWith("../")) {
|
|
54638
|
-
basePath =
|
|
55357
|
+
basePath = resolve6(bindingDir, extendsValue);
|
|
54639
55358
|
} else {
|
|
54640
55359
|
try {
|
|
54641
55360
|
const resolved = import.meta.resolve(extendsValue);
|
|
@@ -54653,7 +55372,7 @@ async function resolveBindingExtends(raw, filePath, seen) {
|
|
|
54653
55372
|
const candidates = ["binding.yaml", "binding.yml"];
|
|
54654
55373
|
let found = false;
|
|
54655
55374
|
for (const name of candidates) {
|
|
54656
|
-
const candidate =
|
|
55375
|
+
const candidate = resolve6(basePath, name);
|
|
54657
55376
|
try {
|
|
54658
55377
|
const cs = await stat2(candidate);
|
|
54659
55378
|
if (cs.isFile()) {
|
|
@@ -55075,10 +55794,10 @@ function collectAllXUsages(dsl) {
|
|
|
55075
55794
|
function extractTemplateXReferences(config) {
|
|
55076
55795
|
const refs = [];
|
|
55077
55796
|
try {
|
|
55078
|
-
const { readFileSync } = __require("fs");
|
|
55797
|
+
const { readFileSync: readFileSync2 } = __require("fs");
|
|
55079
55798
|
for (const target of config.renders) {
|
|
55080
55799
|
try {
|
|
55081
|
-
const content =
|
|
55800
|
+
const content = readFileSync2(target.template, "utf8");
|
|
55082
55801
|
const matches = content.matchAll(/\{\{[^}]*?(x-[\w-]+)[^}]*?\}\}/g);
|
|
55083
55802
|
for (const m2 of matches) refs.push(m2[1]);
|
|
55084
55803
|
} catch {
|
|
@@ -55603,7 +56322,7 @@ var DslTaskResultSchema = z20.object({
|
|
|
55603
56322
|
});
|
|
55604
56323
|
var AuditResultSchema = z20.object({
|
|
55605
56324
|
summary: z20.string(),
|
|
55606
|
-
|
|
56325
|
+
risk_level: z20.enum(["low", "medium", "high", "critical"]),
|
|
55607
56326
|
findings: z20.array(z20.object({
|
|
55608
56327
|
id: z20.string().optional(),
|
|
55609
56328
|
severity: z20.enum(["info", "warning", "error", "critical"]),
|
|
@@ -55621,7 +56340,7 @@ var AuditResultSchema = z20.object({
|
|
|
55621
56340
|
})).optional(),
|
|
55622
56341
|
details: z20.record(z20.string(), z20.unknown()).optional()
|
|
55623
56342
|
})),
|
|
55624
|
-
|
|
56343
|
+
recommended_actions: z20.array(z20.object({
|
|
55625
56344
|
kind: z20.enum(["run_command", "edit_file", "review", "confirm", "block", "ignore"]),
|
|
55626
56345
|
title: z20.string(),
|
|
55627
56346
|
command: z20.string().optional(),
|
|
@@ -55632,7 +56351,7 @@ var AuditResultSchema = z20.object({
|
|
|
55632
56351
|
tool: z20.string().optional(),
|
|
55633
56352
|
command: z20.string().optional(),
|
|
55634
56353
|
version: z20.string().optional(),
|
|
55635
|
-
|
|
56354
|
+
generated_at: z20.string().optional(),
|
|
55636
56355
|
adapter: z20.string().optional(),
|
|
55637
56356
|
model: z20.string().optional()
|
|
55638
56357
|
}).optional()
|
|
@@ -55911,7 +56630,7 @@ function computeExitCode(results, failOn) {
|
|
|
55911
56630
|
|
|
55912
56631
|
// src/guardrail-generator/generator.ts
|
|
55913
56632
|
import { readFile as readFile6, writeFile as writeFile2, mkdir as mkdir2, chmod, unlink as unlink2, copyFile } from "fs/promises";
|
|
55914
|
-
import { resolve as
|
|
56633
|
+
import { resolve as resolve7, dirname as dirname6 } from "path";
|
|
55915
56634
|
import Handlebars2 from "handlebars";
|
|
55916
56635
|
import YAML from "yaml";
|
|
55917
56636
|
|
|
@@ -56133,9 +56852,9 @@ async function generateGuardrails(options) {
|
|
|
56133
56852
|
if (pathResult.diagnostics.some((d2) => d2.severity === "error")) {
|
|
56134
56853
|
continue;
|
|
56135
56854
|
}
|
|
56136
|
-
const targetPath =
|
|
56855
|
+
const targetPath = resolve7(config.configDir, pathResult.resolved);
|
|
56137
56856
|
if (outputDef.source) {
|
|
56138
|
-
const sourcePath =
|
|
56857
|
+
const sourcePath = resolve7(config.configDir, outputDef.source);
|
|
56139
56858
|
if (!dryRun) {
|
|
56140
56859
|
try {
|
|
56141
56860
|
await mkdir2(dirname6(targetPath), { recursive: true });
|
|
@@ -56171,7 +56890,7 @@ async function generateGuardrails(options) {
|
|
|
56171
56890
|
});
|
|
56172
56891
|
continue;
|
|
56173
56892
|
}
|
|
56174
|
-
const templatePath =
|
|
56893
|
+
const templatePath = resolve7(config.configDir, outputDef.template);
|
|
56175
56894
|
try {
|
|
56176
56895
|
templateContent = await readFile6(templatePath, "utf8");
|
|
56177
56896
|
} catch {
|
|
@@ -56210,7 +56929,7 @@ async function generateGuardrails(options) {
|
|
|
56210
56929
|
};
|
|
56211
56930
|
const compiled = Handlebars2.compile(templateContent, { noEscape: true });
|
|
56212
56931
|
const rendered = compiled(groupCtx);
|
|
56213
|
-
const groupTarget =
|
|
56932
|
+
const groupTarget = resolve7(targetPath, groupKey);
|
|
56214
56933
|
if (shouldSkipEmpty && rendered.trim().length === 0) {
|
|
56215
56934
|
if (!dryRun) {
|
|
56216
56935
|
try {
|
|
@@ -56258,7 +56977,7 @@ async function generateGuardrails(options) {
|
|
|
56258
56977
|
if (renderTarget.inline_template) {
|
|
56259
56978
|
templateContent = renderTarget.inline_template;
|
|
56260
56979
|
} else if (renderTarget.template) {
|
|
56261
|
-
const templatePath =
|
|
56980
|
+
const templatePath = resolve7(config.configDir, renderTarget.template);
|
|
56262
56981
|
try {
|
|
56263
56982
|
templateContent = await readFile6(templatePath, "utf8");
|
|
56264
56983
|
} catch {
|
|
@@ -56280,12 +56999,12 @@ async function generateGuardrails(options) {
|
|
|
56280
56999
|
const compiled = Handlebars2.compile(templateContent, { noEscape: true });
|
|
56281
57000
|
const shouldSkipEmpty = renderTarget.skip_empty === true;
|
|
56282
57001
|
const context = renderTarget.context;
|
|
56283
|
-
if (context === "system") {
|
|
56284
|
-
const
|
|
56285
|
-
const mergedCtx = { ...
|
|
57002
|
+
if (context === "system" || context === "navigation_index") {
|
|
57003
|
+
const baseCtx = context === "system" ? buildSystemContext(dsl) : buildNavigationIndex(dsl);
|
|
57004
|
+
const mergedCtx = { ...baseCtx, vars, paths, binding, resolved_checks: checkResult.resolved };
|
|
56286
57005
|
const rendered = compiled(mergedCtx);
|
|
56287
57006
|
const resolvedOutput = resolveBindingRenderOutputPath(renderTarget.output, paths);
|
|
56288
|
-
const outputPath =
|
|
57007
|
+
const outputPath = resolve7(config.configDir, resolvedOutput);
|
|
56289
57008
|
if (shouldSkipEmpty && rendered.trim().length === 0) {
|
|
56290
57009
|
if (!dryRun) {
|
|
56291
57010
|
try {
|
|
@@ -56315,7 +57034,7 @@ async function generateGuardrails(options) {
|
|
|
56315
57034
|
const expandedOutput = expandOutputPath(renderTarget.output, context, entityId, entity);
|
|
56316
57035
|
if (hasUnresolvedPathVars(expandedOutput)) continue;
|
|
56317
57036
|
const resolvedOutput = resolveBindingRenderOutputPath(expandedOutput, paths);
|
|
56318
|
-
const outputPath =
|
|
57037
|
+
const outputPath = resolve7(config.configDir, resolvedOutput);
|
|
56319
57038
|
if (shouldSkipEmpty && rendered.trim().length === 0) {
|
|
56320
57039
|
if (!dryRun) {
|
|
56321
57040
|
try {
|
|
@@ -56405,6 +57124,7 @@ export {
|
|
|
56405
57124
|
buildGuardrailContext,
|
|
56406
57125
|
buildGuardrailPolicyContext,
|
|
56407
57126
|
buildHandoffTypeContext,
|
|
57127
|
+
buildNavigationIndex,
|
|
56408
57128
|
buildPerAgentContext,
|
|
56409
57129
|
buildPolicyContext,
|
|
56410
57130
|
buildSystemContext,
|