@moldea.ai/core 6.0.0 → 7.0.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 +13 -19
- package/dist/analysis-worker.js +14 -24
- package/dist/analysis-worker.js.map +1 -1
- package/dist/binding-coverage/index.d.ts +26 -0
- package/dist/binding-coverage/index.d.ts.map +1 -0
- package/dist/chunks/{core-DchheNDz.js → core-Cdeiu6xG.js} +743 -2684
- package/dist/chunks/core-Cdeiu6xG.js.map +1 -0
- package/dist/chunks/{errors-BQI1DEqf.js → errors-BE4DS3Ak.js} +27 -38
- package/dist/chunks/errors-BE4DS3Ak.js.map +1 -0
- package/dist/chunks/{exceptions-lzD3buFw.js → exceptions-IXsorE8t.js} +4 -16
- package/dist/chunks/exceptions-IXsorE8t.js.map +1 -0
- package/dist/chunks/{lifecycle-4EkWgEHm.js → lifecycle-D_RvxhDC.js} +2 -2
- package/dist/chunks/{lifecycle-4EkWgEHm.js.map → lifecycle-D_RvxhDC.js.map} +1 -1
- package/dist/chunks/{options-CxCT3dZU.js → options-5x9gu2Qb.js} +139 -152
- package/dist/chunks/options-5x9gu2Qb.js.map +1 -0
- package/dist/chunks/{repository-rpc-BWi6X1la.js → repository-rpc-B_y0Kspf.js} +2 -2
- package/dist/chunks/{repository-rpc-BWi6X1la.js.map → repository-rpc-B_y0Kspf.js.map} +1 -1
- package/dist/chunks/scope-AGMcHUE_.js +1827 -0
- package/dist/chunks/scope-AGMcHUE_.js.map +1 -0
- package/dist/chunks/syntax-CVvExx4R.js +137 -0
- package/dist/chunks/syntax-CVvExx4R.js.map +1 -0
- package/dist/constants/index.d.ts +2 -1
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +15 -15
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/core/index.d.ts +1 -4
- package/dist/core/index.d.ts.map +1 -1
- package/dist/decision/index.d.ts +1 -1
- package/dist/decision-graph/index.d.ts +9 -7
- package/dist/decision-graph/index.d.ts.map +1 -1
- package/dist/diagnostic-utilities/index.d.ts +6 -2
- package/dist/diagnostic-utilities/index.d.ts.map +1 -1
- package/dist/diagnostics/index.d.ts +21 -33
- package/dist/diagnostics/index.d.ts.map +1 -1
- package/dist/exceptions/index.d.ts +4 -8
- package/dist/exceptions/index.d.ts.map +1 -1
- package/dist/export-inventory/index.d.ts +3 -0
- package/dist/export-inventory/index.d.ts.map +1 -0
- package/dist/export-inventory/inventory.d.ts +22 -0
- package/dist/export-inventory/inventory.d.ts.map +1 -0
- package/dist/export-inventory/syntax.d.ts +4 -0
- package/dist/export-inventory/syntax.d.ts.map +1 -0
- package/dist/export-inventory/types.d.ts +9 -0
- package/dist/export-inventory/types.d.ts.map +1 -0
- package/dist/format/index.d.ts +8 -0
- package/dist/format/index.d.ts.map +1 -1
- package/dist/impact-pattern-validation/index.d.ts +2 -0
- package/dist/impact-pattern-validation/index.d.ts.map +1 -0
- package/dist/impact-pattern-validation/inspection.d.ts +24 -0
- package/dist/impact-pattern-validation/inspection.d.ts.map +1 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/integration-validation/index.d.ts +4 -0
- package/dist/integration-validation/index.d.ts.map +1 -0
- package/dist/integration-validation/inspection.d.ts +18 -0
- package/dist/integration-validation/inspection.d.ts.map +1 -0
- package/dist/integration-validation/parser.d.ts +9 -0
- package/dist/integration-validation/parser.d.ts.map +1 -0
- package/dist/integration-validation/types.d.ts +13 -0
- package/dist/integration-validation/types.d.ts.map +1 -0
- package/dist/manifest/index.d.ts +2 -4
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest-validation/index.d.ts +7 -10
- package/dist/manifest-validation/index.d.ts.map +1 -1
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node-inspection/client.d.ts +0 -4
- package/dist/node-inspection/client.d.ts.map +1 -1
- package/dist/node-inspection/errors.d.ts.map +1 -1
- package/dist/node-inspection/protocol.d.ts.map +1 -1
- package/dist/node-inspection/types.d.ts +4 -8
- package/dist/node-inspection/types.d.ts.map +1 -1
- package/dist/node-runner.js +4 -4
- package/dist/node-runner.js.map +1 -1
- package/dist/node.js +23 -13
- package/dist/node.js.map +1 -1
- package/dist/options/index.d.ts +2 -14
- package/dist/options/index.d.ts.map +1 -1
- package/dist/project-inspection/index.d.ts +1 -2
- package/dist/project-inspection/index.d.ts.map +1 -1
- package/dist/project-validation/index.d.ts +2 -4
- package/dist/project-validation/index.d.ts.map +1 -1
- package/dist/repository-inspection-session/index.d.ts +2 -4
- package/dist/repository-inspection-session/index.d.ts.map +1 -1
- package/dist/repository-reference-validation/index.d.ts +12 -6
- package/dist/repository-reference-validation/index.d.ts.map +1 -1
- package/dist/retained-memory/index.d.ts +18 -0
- package/dist/retained-memory/index.d.ts.map +1 -0
- package/dist/scope/index.d.ts +3 -0
- package/dist/scope/index.d.ts.map +1 -0
- package/dist/scope/scope.d.ts +13 -0
- package/dist/scope/scope.d.ts.map +1 -0
- package/dist/scope-matching/index.d.ts +2 -1
- package/dist/scope-matching/index.d.ts.map +1 -1
- package/dist/scope-matching/matching.d.ts +11 -2
- package/dist/scope-matching/matching.d.ts.map +1 -1
- package/dist/scope-matching/patterns.d.ts +4 -0
- package/dist/scope-matching/patterns.d.ts.map +1 -0
- package/dist/scope.js +17 -0
- package/dist/scope.js.map +1 -0
- package/dist/universal-project-inspection/index.d.ts +13 -11
- package/dist/universal-project-inspection/index.d.ts.map +1 -1
- package/dist/warning-acceptance/acceptance.d.ts +11 -0
- package/dist/warning-acceptance/acceptance.d.ts.map +1 -0
- package/dist/warning-acceptance/index.d.ts +2 -0
- package/dist/warning-acceptance/index.d.ts.map +1 -0
- package/package.json +6 -6
- package/dist/adapter/index.d.ts +0 -143
- package/dist/adapter/index.d.ts.map +0 -1
- package/dist/adapter-availability/index.d.ts +0 -15
- package/dist/adapter-availability/index.d.ts.map +0 -1
- package/dist/adapter-execution/index.d.ts +0 -34
- package/dist/adapter-execution/index.d.ts.map +0 -1
- package/dist/adapter-repository/index.d.ts +0 -27
- package/dist/adapter-repository/index.d.ts.map +0 -1
- package/dist/adapter-result-collection/collection.d.ts +0 -13
- package/dist/adapter-result-collection/collection.d.ts.map +0 -1
- package/dist/adapter-result-collection/index.d.ts +0 -3
- package/dist/adapter-result-collection/index.d.ts.map +0 -1
- package/dist/adapter-result-collection/types.d.ts +0 -31
- package/dist/adapter-result-collection/types.d.ts.map +0 -1
- package/dist/adapter-retained-memory/index.d.ts +0 -8
- package/dist/adapter-retained-memory/index.d.ts.map +0 -1
- package/dist/adapter-validation/index.d.ts +0 -43
- package/dist/adapter-validation/index.d.ts.map +0 -1
- package/dist/adapter.js +0 -116
- package/dist/adapter.js.map +0 -1
- package/dist/chunks/collection-CvbjjLf2.js +0 -73
- package/dist/chunks/collection-CvbjjLf2.js.map +0 -1
- package/dist/chunks/core-DchheNDz.js.map +0 -1
- package/dist/chunks/errors-BQI1DEqf.js.map +0 -1
- package/dist/chunks/exceptions-lzD3buFw.js.map +0 -1
- package/dist/chunks/options-CxCT3dZU.js.map +0 -1
- package/dist/custom-runtime-inspection/index.d.ts +0 -2
- package/dist/custom-runtime-inspection/index.d.ts.map +0 -1
- package/dist/custom-runtime-inspection/inspection.d.ts +0 -11
- package/dist/custom-runtime-inspection/inspection.d.ts.map +0 -1
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { n as CoreOperationException } from "./exceptions-
|
|
3
|
-
import {
|
|
4
|
-
import { REPOSITORY_ROOT,
|
|
5
|
-
import { Parser, isAlias, isMap, isScalar, isSeq, parseAllDocuments } from "yaml";
|
|
1
|
+
import { E as parseDecisionIdFromPath, S as isRuntimeGuidancePath, T as isVariableId, a as escapeJsonPointerSegment, c as freezeRecursively, d as hasNonWhitespace, g as isContextPath, i as createCoreDiagnosticCollector, k as trimRepositoryFormatWhitespace, l as compareExactStrings, n as normalizeCoreOptions, o as normalizeDiagnostics, r as countDiagnosticsBySeverity, s as createNullPrototypeRecord, t as createCoreOperationOptionsSnapshot, u as countUnicodeScalars } from "./options-5x9gu2Qb.js";
|
|
2
|
+
import { n as CoreOperationException } from "./exceptions-IXsorE8t.js";
|
|
3
|
+
import { a as createSourceLocator, c as calculateContentDigest, i as parseStrictYaml, l as calculateNormalizedTextDigest, n as inspectManifestDocument, o as collectManifestScopeDeclarations, r as parseManifestDocument, s as matchesRepositoryGlob, t as matchManifestScope, u as normalizeTextDocument } from "./scope-AGMcHUE_.js";
|
|
4
|
+
import { REPOSITORY_ROOT, RepositorySourceException, compareRepositoryPaths, createRepositoryIdentity, isRepositoryPath, parseRepositoryPath } from "@moldea.ai/repository";
|
|
6
5
|
//#region \0rolldown/runtime.js
|
|
7
6
|
var __defProp = Object.defineProperty;
|
|
8
7
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -16,11 +15,11 @@ var __exportAll = (all, no_symbols) => {
|
|
|
16
15
|
};
|
|
17
16
|
//#endregion
|
|
18
17
|
//#region src/canonical-content-page/index.ts
|
|
19
|
-
var decoder
|
|
18
|
+
var decoder = new TextDecoder("utf-8", {
|
|
20
19
|
fatal: true,
|
|
21
20
|
ignoreBOM: true
|
|
22
21
|
});
|
|
23
|
-
var invalidArgument$
|
|
22
|
+
var invalidArgument$2 = () => {
|
|
24
23
|
throw new CoreOperationException({
|
|
25
24
|
code: "INVALID_ARGUMENT",
|
|
26
25
|
operation: "read-canonical-content-page"
|
|
@@ -64,7 +63,7 @@ var readBytes = async (repository, path, offset, maxBytes, signal) => {
|
|
|
64
63
|
});
|
|
65
64
|
nextOffset = page.nextOffset;
|
|
66
65
|
}
|
|
67
|
-
if (lastPage === null) return invalidArgument$
|
|
66
|
+
if (lastPage === null) return invalidArgument$2();
|
|
68
67
|
const bytes = new Uint8Array(byteLength);
|
|
69
68
|
let writeOffset = 0;
|
|
70
69
|
for (const chunk of chunks) {
|
|
@@ -79,7 +78,7 @@ var readBytes = async (repository, path, offset, maxBytes, signal) => {
|
|
|
79
78
|
var decodeSafePrefix = (bytes, maximumBytes) => {
|
|
80
79
|
const minimumCandidate = Math.max(0, maximumBytes - 3);
|
|
81
80
|
for (let end = maximumBytes; end >= minimumCandidate; end -= 1) try {
|
|
82
|
-
const content = decoder
|
|
81
|
+
const content = decoder.decode(bytes.subarray(0, end));
|
|
83
82
|
if (end === 0 && bytes.byteLength > 0) continue;
|
|
84
83
|
return [content, end];
|
|
85
84
|
} catch {}
|
|
@@ -87,9 +86,9 @@ var decodeSafePrefix = (bytes, maximumBytes) => {
|
|
|
87
86
|
};
|
|
88
87
|
/** Reads one explicit canonical file range without materializing the complete file. */
|
|
89
88
|
var readCanonicalContentPage = async (input, options) => {
|
|
90
|
-
if (typeof input !== "object" || input === null || Reflect.ownKeys(input).some((key) => key !== "maxBytes" && key !== "offset" && key !== "path" && key !== "repository" && key !== "signal") || !isRepositoryReader$1(input.repository) || !Number.isSafeInteger(input.maxBytes) || input.maxBytes < 1 || input.maxBytes > options.limits.maxFileBytes || !Number.isSafeInteger(input.offset) || input.offset < 0) return invalidArgument$
|
|
89
|
+
if (typeof input !== "object" || input === null || Reflect.ownKeys(input).some((key) => key !== "maxBytes" && key !== "offset" && key !== "path" && key !== "repository" && key !== "signal") || !isRepositoryReader$1(input.repository) || !Number.isSafeInteger(input.maxBytes) || input.maxBytes < 1 || input.maxBytes > options.limits.maxFileBytes || !Number.isSafeInteger(input.offset) || input.offset < 0) return invalidArgument$2();
|
|
91
90
|
const path = parseRepositoryPath(input.path);
|
|
92
|
-
if (!path.startsWith("/moldea/")) return invalidArgument$
|
|
91
|
+
if (!path.startsWith("/moldea/")) return invalidArgument$2();
|
|
93
92
|
const operationOptions = input.signal === void 0 ? void 0 : { signal: input.signal };
|
|
94
93
|
const entry = await input.repository.getEntry(path, operationOptions);
|
|
95
94
|
if (entry === null) throw new RepositorySourceException({
|
|
@@ -112,7 +111,7 @@ var readCanonicalContentPage = async (input, options) => {
|
|
|
112
111
|
observedUsage: entry.byteLength,
|
|
113
112
|
operation: "read-canonical-content-page"
|
|
114
113
|
});
|
|
115
|
-
if (input.offset > entry.byteLength) return invalidArgument$
|
|
114
|
+
if (input.offset > entry.byteLength) return invalidArgument$2();
|
|
116
115
|
if (input.offset === entry.byteLength) return freezeRecursively({
|
|
117
116
|
byteEnd: input.offset,
|
|
118
117
|
byteStart: input.offset,
|
|
@@ -126,7 +125,7 @@ var readCanonicalContentPage = async (input, options) => {
|
|
|
126
125
|
});
|
|
127
126
|
const lookaheadBytes = Math.min(entry.byteLength - input.offset, input.maxBytes + 3);
|
|
128
127
|
const { bytes, lastPage } = await readBytes(input.repository, path, input.offset, lookaheadBytes, input.signal);
|
|
129
|
-
if (lastPage.totalBytes !== entry.byteLength || (bytes[0] & 192) === 128) return invalidArgument$
|
|
128
|
+
if (lastPage.totalBytes !== entry.byteLength || (bytes[0] & 192) === 128) return invalidArgument$2();
|
|
130
129
|
const [content, consumedBytes] = decodeSafePrefix(bytes, Math.min(input.maxBytes, bytes.byteLength));
|
|
131
130
|
const byteEnd = input.offset + consumedBytes;
|
|
132
131
|
const isComplete = byteEnd === entry.byteLength;
|
|
@@ -170,7 +169,7 @@ var isCanonicalCreatedAt = (value) => {
|
|
|
170
169
|
const timestamp = Date.parse(value);
|
|
171
170
|
return Number.isFinite(timestamp) && new Date(timestamp).toISOString() === value;
|
|
172
171
|
};
|
|
173
|
-
var readMapping
|
|
172
|
+
var readMapping = (node, context) => {
|
|
174
173
|
if (node.kind !== "mapping") {
|
|
175
174
|
addInvalidFrontmatter(context, node.range, "mapping-required");
|
|
176
175
|
return null;
|
|
@@ -315,7 +314,7 @@ var extractDecisionSections = (value, locator, context) => {
|
|
|
315
314
|
*/
|
|
316
315
|
var validateDecisionFrontmatter = (node, context) => {
|
|
317
316
|
const initialDiagnosticCount = context.diagnostics.size;
|
|
318
|
-
const entries = readMapping
|
|
317
|
+
const entries = readMapping(node, context);
|
|
319
318
|
if (entries === null) return null;
|
|
320
319
|
const status = readStatus(entries.get("status"), context);
|
|
321
320
|
const createdAt = readCreatedAt(entries.get("createdAt"), context);
|
|
@@ -339,500 +338,11 @@ var validateDecisionBody = (body, range, context) => {
|
|
|
339
338
|
return false;
|
|
340
339
|
};
|
|
341
340
|
//#endregion
|
|
342
|
-
//#region src/source-location/index.ts
|
|
343
|
-
var findLineIndex = (lineStarts, offset) => {
|
|
344
|
-
let lower = 0;
|
|
345
|
-
let upper = lineStarts.length - 1;
|
|
346
|
-
while (lower < upper) {
|
|
347
|
-
const middle = Math.ceil((lower + upper) / 2);
|
|
348
|
-
if ((lineStarts[middle] ?? 0) <= offset) lower = middle;
|
|
349
|
-
else upper = middle - 1;
|
|
350
|
-
}
|
|
351
|
-
return lower;
|
|
352
|
-
};
|
|
353
|
-
/**
|
|
354
|
-
* Creates an efficient UTF-16-offset to Unicode-scalar source locator.
|
|
355
|
-
* @param value The already-normalized valid Unicode scalar text.
|
|
356
|
-
* @returns A locator producing one-based lines and columns with zero-based scalar offsets.
|
|
357
|
-
*/
|
|
358
|
-
var createSourceLocator = (value) => {
|
|
359
|
-
const scalarOffsets = new Uint32Array(value.length + 1);
|
|
360
|
-
const lineStarts = [0];
|
|
361
|
-
let scalarOffset = 0;
|
|
362
|
-
for (let codeUnitOffset = 0; codeUnitOffset < value.length;) {
|
|
363
|
-
const codePoint = value.codePointAt(codeUnitOffset);
|
|
364
|
-
const width = codePoint !== void 0 && codePoint > 65535 ? 2 : 1;
|
|
365
|
-
scalarOffsets[codeUnitOffset] = scalarOffset;
|
|
366
|
-
for (let interiorOffset = 1; interiorOffset < width; interiorOffset += 1) scalarOffsets[codeUnitOffset + interiorOffset] = scalarOffset;
|
|
367
|
-
codeUnitOffset += width;
|
|
368
|
-
scalarOffset += 1;
|
|
369
|
-
scalarOffsets[codeUnitOffset] = scalarOffset;
|
|
370
|
-
if (codePoint === 10) lineStarts.push(codeUnitOffset);
|
|
371
|
-
}
|
|
372
|
-
const locatePosition = (candidateOffset) => {
|
|
373
|
-
const codeUnitOffset = Math.max(0, Math.min(value.length, candidateOffset));
|
|
374
|
-
const lineIndex = findLineIndex(lineStarts, codeUnitOffset);
|
|
375
|
-
const lineStart = lineStarts[lineIndex] ?? 0;
|
|
376
|
-
const positionScalarOffset = scalarOffsets[codeUnitOffset] ?? 0;
|
|
377
|
-
return {
|
|
378
|
-
column: positionScalarOffset - (scalarOffsets[lineStart] ?? 0) + 1,
|
|
379
|
-
line: lineIndex + 1,
|
|
380
|
-
offset: positionScalarOffset
|
|
381
|
-
};
|
|
382
|
-
};
|
|
383
|
-
return Object.freeze({ locateRange: (startOffset, endOffset) => ({
|
|
384
|
-
end: locatePosition(endOffset),
|
|
385
|
-
start: locatePosition(startOffset)
|
|
386
|
-
}) });
|
|
387
|
-
};
|
|
388
|
-
//#endregion
|
|
389
|
-
//#region src/text/index.ts
|
|
390
|
-
var encoder$2 = new TextEncoder();
|
|
391
|
-
var decoder = new TextDecoder("utf-8", {
|
|
392
|
-
fatal: true,
|
|
393
|
-
ignoreBOM: true
|
|
394
|
-
});
|
|
395
|
-
var isRecord$3 = (value) => {
|
|
396
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
397
|
-
};
|
|
398
|
-
/**
|
|
399
|
-
* Measures valid scalar UTF-8 bytes and stops once the operation budget is exceeded.
|
|
400
|
-
* @param value The decoded string to measure without lossy replacement.
|
|
401
|
-
* @param maximumByteLength The threshold after which measurement may stop early.
|
|
402
|
-
* @returns The measured bytes, a value above the threshold, or `null` for invalid Unicode.
|
|
403
|
-
*/
|
|
404
|
-
var measureScalarUtf8ByteLength = (value, maximumByteLength) => {
|
|
405
|
-
let byteLength = 0;
|
|
406
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
407
|
-
const codeUnit = value.charCodeAt(index);
|
|
408
|
-
if (codeUnit >= 55296 && codeUnit <= 56319) {
|
|
409
|
-
if (index + 1 >= value.length) return null;
|
|
410
|
-
const nextCodeUnit = value.charCodeAt(index + 1);
|
|
411
|
-
if (nextCodeUnit < 56320 || nextCodeUnit > 57343) return null;
|
|
412
|
-
byteLength += 4;
|
|
413
|
-
if (byteLength > maximumByteLength) return byteLength;
|
|
414
|
-
index += 1;
|
|
415
|
-
continue;
|
|
416
|
-
}
|
|
417
|
-
if (codeUnit >= 56320 && codeUnit <= 57343) return null;
|
|
418
|
-
byteLength += codeUnit <= 127 ? 1 : codeUnit <= 2047 ? 2 : 3;
|
|
419
|
-
if (byteLength > maximumByteLength) return byteLength;
|
|
420
|
-
}
|
|
421
|
-
return byteLength;
|
|
422
|
-
};
|
|
423
|
-
var countUnicodeScalars = (value) => {
|
|
424
|
-
let count = 0;
|
|
425
|
-
for (let index = 0; index < value.length; count += 1) {
|
|
426
|
-
const codePoint = value.codePointAt(index);
|
|
427
|
-
if (codePoint === void 0) break;
|
|
428
|
-
index += codePoint > 65535 ? 2 : 1;
|
|
429
|
-
}
|
|
430
|
-
return count;
|
|
431
|
-
};
|
|
432
|
-
/**
|
|
433
|
-
* Collects every normalized NUL location or rejects when the diagnostic budget is exhausted.
|
|
434
|
-
* @param value The normalized scalar text to inspect.
|
|
435
|
-
* @param path The logical document path attached to each diagnostic.
|
|
436
|
-
* @param diagnostics The operation collector receiving every NUL diagnostic.
|
|
437
|
-
* @throws
|
|
438
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
439
|
-
*/
|
|
440
|
-
var collectNulDiagnostics = (value, path, diagnostics) => {
|
|
441
|
-
let column = 1;
|
|
442
|
-
let line = 1;
|
|
443
|
-
let offset = 0;
|
|
444
|
-
for (const scalar of value) {
|
|
445
|
-
if (scalar === "\0") diagnostics.add({
|
|
446
|
-
code: "MOLDEA_TEXT_NUL_FORBIDDEN",
|
|
447
|
-
path,
|
|
448
|
-
range: {
|
|
449
|
-
end: {
|
|
450
|
-
column: column + 1,
|
|
451
|
-
line,
|
|
452
|
-
offset: offset + 1
|
|
453
|
-
},
|
|
454
|
-
start: {
|
|
455
|
-
column,
|
|
456
|
-
line,
|
|
457
|
-
offset
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
});
|
|
461
|
-
if (scalar === "\n") {
|
|
462
|
-
column = 1;
|
|
463
|
-
line += 1;
|
|
464
|
-
} else column += 1;
|
|
465
|
-
offset += 1;
|
|
466
|
-
}
|
|
467
|
-
};
|
|
468
|
-
var invalidArgument$3 = (operation) => {
|
|
469
|
-
throw new CoreOperationException({
|
|
470
|
-
code: "INVALID_ARGUMENT",
|
|
471
|
-
operation
|
|
472
|
-
});
|
|
473
|
-
};
|
|
474
|
-
var enforceFileLimit = (byteLength, limits, operation, limit) => {
|
|
475
|
-
if (byteLength <= limits[limit]) return;
|
|
476
|
-
throw new CoreOperationException({
|
|
477
|
-
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
478
|
-
limit,
|
|
479
|
-
limitMaximum: limits[limit],
|
|
480
|
-
nextAction: "reduce-input-or-increase-limit",
|
|
481
|
-
observedUsage: byteLength,
|
|
482
|
-
operation
|
|
483
|
-
});
|
|
484
|
-
};
|
|
485
|
-
var invalidResult = (diagnostics) => {
|
|
486
|
-
return freezeRecursively({
|
|
487
|
-
diagnostics: [...diagnostics],
|
|
488
|
-
text: null,
|
|
489
|
-
valid: false
|
|
490
|
-
});
|
|
491
|
-
};
|
|
492
|
-
/**
|
|
493
|
-
* Validates one public text input, enforces its source-byte budget, and decodes strict UTF-8.
|
|
494
|
-
* @param input The untrusted public text-document input.
|
|
495
|
-
* @param limits The immutable Core resource limits.
|
|
496
|
-
* @param operation The public operation requesting the input.
|
|
497
|
-
* @param limit The source-byte limit applied by the operation.
|
|
498
|
-
* @param diagnostics The operation collector receiving text diagnostics.
|
|
499
|
-
* @returns Decoded text or a frozen structural failure result.
|
|
500
|
-
* @throws
|
|
501
|
-
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
502
|
-
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
503
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
504
|
-
*/
|
|
505
|
-
var readInput = (input, limits, operation, limit, diagnostics) => {
|
|
506
|
-
if (!isRecord$3(input)) return invalidArgument$3(operation);
|
|
507
|
-
const pathCandidate = input["path"];
|
|
508
|
-
const content = input["content"];
|
|
509
|
-
if (typeof pathCandidate !== "string" || typeof content !== "string" && !(content instanceof Uint8Array)) return invalidArgument$3(operation);
|
|
510
|
-
const path = parseRepositoryPath(pathCandidate);
|
|
511
|
-
if (typeof content === "string") {
|
|
512
|
-
const byteLength = measureScalarUtf8ByteLength(content, limits[limit]);
|
|
513
|
-
if (byteLength === null) {
|
|
514
|
-
diagnostics.add({
|
|
515
|
-
code: "MOLDEA_TEXT_INVALID_UNICODE",
|
|
516
|
-
path
|
|
517
|
-
});
|
|
518
|
-
return invalidResult(diagnostics.finalize());
|
|
519
|
-
}
|
|
520
|
-
enforceFileLimit(byteLength, limits, operation, limit);
|
|
521
|
-
return {
|
|
522
|
-
path,
|
|
523
|
-
value: content
|
|
524
|
-
};
|
|
525
|
-
}
|
|
526
|
-
enforceFileLimit(content.byteLength, limits, operation, limit);
|
|
527
|
-
const bytes = new Uint8Array(content);
|
|
528
|
-
try {
|
|
529
|
-
return {
|
|
530
|
-
path,
|
|
531
|
-
value: decoder.decode(bytes)
|
|
532
|
-
};
|
|
533
|
-
} catch {
|
|
534
|
-
diagnostics.add({
|
|
535
|
-
code: "MOLDEA_TEXT_INVALID_UTF8",
|
|
536
|
-
path
|
|
537
|
-
});
|
|
538
|
-
return invalidResult(diagnostics.finalize());
|
|
539
|
-
}
|
|
540
|
-
};
|
|
541
|
-
/**
|
|
542
|
-
* Validates and normalizes one text document under an operation-specific resource budget.
|
|
543
|
-
* @param input The logical path and decoded string or exact source bytes.
|
|
544
|
-
* @param limits The immutable Core resource limits.
|
|
545
|
-
* @param operation The public Core operation requesting normalization.
|
|
546
|
-
* @param limit The source-byte limit applied by the operation.
|
|
547
|
-
* @returns A frozen normalized result or structural text diagnostics.
|
|
548
|
-
* @throws
|
|
549
|
-
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
550
|
-
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
551
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
552
|
-
*/
|
|
553
|
-
var normalizeTextDocument = (input, limits, operation, limit = "maxFileBytes") => {
|
|
554
|
-
const diagnostics = createCoreDiagnosticCollector(limits, operation);
|
|
555
|
-
const decoded = readInput(input, limits, operation, limit, diagnostics);
|
|
556
|
-
if ("valid" in decoded) return decoded;
|
|
557
|
-
const value = (decoded.value.startsWith("") ? decoded.value.slice(1) : decoded.value).replace(/\r\n?/gu, "\n");
|
|
558
|
-
collectNulDiagnostics(value, decoded.path, diagnostics);
|
|
559
|
-
if (diagnostics.size > 0) return invalidResult(diagnostics.finalize());
|
|
560
|
-
const text = freezeRecursively({
|
|
561
|
-
scalarLength: countUnicodeScalars(value),
|
|
562
|
-
utf8ByteLength: encoder$2.encode(value).byteLength,
|
|
563
|
-
value
|
|
564
|
-
});
|
|
565
|
-
return freezeRecursively({
|
|
566
|
-
diagnostics: [],
|
|
567
|
-
text,
|
|
568
|
-
valid: true
|
|
569
|
-
});
|
|
570
|
-
};
|
|
571
|
-
var toLowercaseHex = (bytes) => {
|
|
572
|
-
let value = "";
|
|
573
|
-
for (const byte of bytes) value += byte.toString(16).padStart(2, "0");
|
|
574
|
-
return value;
|
|
575
|
-
};
|
|
576
|
-
/**
|
|
577
|
-
* Calculates the canonical digest for already-normalized text.
|
|
578
|
-
* @param text The validated normalized text to encode and hash.
|
|
579
|
-
* @returns A promise resolving to the canonical lowercase SHA-256 digest.
|
|
580
|
-
*/
|
|
581
|
-
var calculateNormalizedTextDigest = async (text) => {
|
|
582
|
-
const bytes = encoder$2.encode(text.value);
|
|
583
|
-
return `sha256:${toLowercaseHex(new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", bytes)))}`;
|
|
584
|
-
};
|
|
585
|
-
/**
|
|
586
|
-
* Calculates the normalized SHA-256 digest for one text document.
|
|
587
|
-
* @param input The logical path and decoded string or exact source bytes.
|
|
588
|
-
* @param limits The immutable Core resource limits.
|
|
589
|
-
* @returns A promise resolving to a frozen digest result or structural text diagnostics.
|
|
590
|
-
* @throws
|
|
591
|
-
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
592
|
-
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
593
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
594
|
-
*/
|
|
595
|
-
var calculateContentDigest = async (input, limits) => {
|
|
596
|
-
const normalized = normalizeTextDocument(input, limits, "calculate-content-digest");
|
|
597
|
-
if (!normalized.valid || normalized.text === null) return freezeRecursively({
|
|
598
|
-
diagnostics: normalized.diagnostics,
|
|
599
|
-
digest: null,
|
|
600
|
-
text: null,
|
|
601
|
-
valid: false
|
|
602
|
-
});
|
|
603
|
-
const digest = await calculateNormalizedTextDigest(normalized.text);
|
|
604
|
-
return freezeRecursively({
|
|
605
|
-
diagnostics: [],
|
|
606
|
-
digest,
|
|
607
|
-
text: normalized.text,
|
|
608
|
-
valid: true
|
|
609
|
-
});
|
|
610
|
-
};
|
|
611
|
-
//#endregion
|
|
612
|
-
//#region src/yaml/index.ts
|
|
613
|
-
var CORE_TAGS = /* @__PURE__ */ new Set([
|
|
614
|
-
"tag:yaml.org,2002:bool",
|
|
615
|
-
"tag:yaml.org,2002:float",
|
|
616
|
-
"tag:yaml.org,2002:int",
|
|
617
|
-
"tag:yaml.org,2002:map",
|
|
618
|
-
"tag:yaml.org,2002:null",
|
|
619
|
-
"tag:yaml.org,2002:seq",
|
|
620
|
-
"tag:yaml.org,2002:str"
|
|
621
|
-
]);
|
|
622
|
-
var toRange = (range, locator) => {
|
|
623
|
-
return locator.locateRange(range?.[0] ?? 0, range?.[1] ?? range?.[0] ?? 0);
|
|
624
|
-
};
|
|
625
|
-
var addUnsupportedFeature = (diagnostics, path, range, reason) => {
|
|
626
|
-
diagnostics.add({
|
|
627
|
-
code: "MOLDEA_YAML_FEATURE_UNSUPPORTED",
|
|
628
|
-
details: { reason },
|
|
629
|
-
path,
|
|
630
|
-
range
|
|
631
|
-
});
|
|
632
|
-
};
|
|
633
|
-
var isUnicodeScalarString = (value) => {
|
|
634
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
635
|
-
const codeUnit = value.charCodeAt(index);
|
|
636
|
-
if (codeUnit >= 55296 && codeUnit <= 56319) {
|
|
637
|
-
const nextCodeUnit = value.charCodeAt(index + 1);
|
|
638
|
-
if (!(nextCodeUnit >= 56320 && nextCodeUnit <= 57343)) return false;
|
|
639
|
-
index += 1;
|
|
640
|
-
} else if (codeUnit >= 56320 && codeUnit <= 57343) return false;
|
|
641
|
-
}
|
|
642
|
-
return true;
|
|
643
|
-
};
|
|
644
|
-
var isCoreTagCompatible = (node) => {
|
|
645
|
-
switch (node.tag) {
|
|
646
|
-
case "tag:yaml.org,2002:bool": return isScalar(node) && typeof node.value === "boolean";
|
|
647
|
-
case "tag:yaml.org,2002:float": return isScalar(node) && typeof node.value === "number";
|
|
648
|
-
case "tag:yaml.org,2002:int": return isScalar(node) && typeof node.value === "bigint";
|
|
649
|
-
case "tag:yaml.org,2002:map": return isMap(node);
|
|
650
|
-
case "tag:yaml.org,2002:null": return isScalar(node) && node.value === null;
|
|
651
|
-
case "tag:yaml.org,2002:seq": return isSeq(node);
|
|
652
|
-
case "tag:yaml.org,2002:str": return isScalar(node) && typeof node.value === "string";
|
|
653
|
-
default: return false;
|
|
654
|
-
}
|
|
655
|
-
};
|
|
656
|
-
var convertNode = (node, path, locator, diagnostics) => {
|
|
657
|
-
const range = toRange(node.range, locator);
|
|
658
|
-
if (isAlias(node)) {
|
|
659
|
-
addUnsupportedFeature(diagnostics, path, range, "alias");
|
|
660
|
-
return null;
|
|
661
|
-
}
|
|
662
|
-
if ("anchor" in node && typeof node.anchor === "string") addUnsupportedFeature(diagnostics, path, range, "anchor");
|
|
663
|
-
if (node.tag !== void 0) {
|
|
664
|
-
if (!CORE_TAGS.has(node.tag)) {
|
|
665
|
-
addUnsupportedFeature(diagnostics, path, range, "custom-tag");
|
|
666
|
-
return null;
|
|
667
|
-
}
|
|
668
|
-
if (!isCoreTagCompatible(node)) {
|
|
669
|
-
diagnostics.add({
|
|
670
|
-
code: "MOLDEA_YAML_MALFORMED",
|
|
671
|
-
details: { reason: "tag-value" },
|
|
672
|
-
path,
|
|
673
|
-
range
|
|
674
|
-
});
|
|
675
|
-
return null;
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
if (isScalar(node)) {
|
|
679
|
-
const value = node.value;
|
|
680
|
-
if (value !== null && typeof value !== "string" && typeof value !== "number" && typeof value !== "bigint" && typeof value !== "boolean") {
|
|
681
|
-
diagnostics.add({
|
|
682
|
-
code: "MOLDEA_YAML_MALFORMED",
|
|
683
|
-
details: { reason: "scalar-type" },
|
|
684
|
-
path,
|
|
685
|
-
range
|
|
686
|
-
});
|
|
687
|
-
return null;
|
|
688
|
-
}
|
|
689
|
-
if (typeof value === "string" && !isUnicodeScalarString(value)) {
|
|
690
|
-
diagnostics.add({
|
|
691
|
-
code: "MOLDEA_YAML_MALFORMED",
|
|
692
|
-
details: { reason: "invalid-unicode" },
|
|
693
|
-
path,
|
|
694
|
-
range
|
|
695
|
-
});
|
|
696
|
-
return null;
|
|
697
|
-
}
|
|
698
|
-
return {
|
|
699
|
-
kind: "scalar",
|
|
700
|
-
range,
|
|
701
|
-
source: node.source,
|
|
702
|
-
style: node.type ?? null,
|
|
703
|
-
value
|
|
704
|
-
};
|
|
705
|
-
}
|
|
706
|
-
if (isSeq(node)) {
|
|
707
|
-
const items = [];
|
|
708
|
-
for (const item of node.items) {
|
|
709
|
-
if (item === null) {
|
|
710
|
-
items.push({
|
|
711
|
-
kind: "scalar",
|
|
712
|
-
range,
|
|
713
|
-
source: "",
|
|
714
|
-
style: null,
|
|
715
|
-
value: null
|
|
716
|
-
});
|
|
717
|
-
continue;
|
|
718
|
-
}
|
|
719
|
-
const converted = convertNode(item, path, locator, diagnostics);
|
|
720
|
-
if (converted !== null) items.push(converted);
|
|
721
|
-
}
|
|
722
|
-
return {
|
|
723
|
-
items,
|
|
724
|
-
kind: "sequence",
|
|
725
|
-
range
|
|
726
|
-
};
|
|
727
|
-
}
|
|
728
|
-
if (isMap(node)) {
|
|
729
|
-
const entries = [];
|
|
730
|
-
for (const pair of node.items) {
|
|
731
|
-
const key = convertNode(pair.key, path, locator, diagnostics);
|
|
732
|
-
const value = pair.value === null ? {
|
|
733
|
-
kind: "scalar",
|
|
734
|
-
range: key?.range ?? range,
|
|
735
|
-
source: "",
|
|
736
|
-
style: null,
|
|
737
|
-
value: null
|
|
738
|
-
} : convertNode(pair.value, path, locator, diagnostics);
|
|
739
|
-
if (key?.kind === "scalar" && key.value === "<<" && key.style === "PLAIN") addUnsupportedFeature(diagnostics, path, key.range, "merge-key");
|
|
740
|
-
if (key !== null && value !== null) entries.push({
|
|
741
|
-
key,
|
|
742
|
-
value
|
|
743
|
-
});
|
|
744
|
-
}
|
|
745
|
-
return {
|
|
746
|
-
entries,
|
|
747
|
-
kind: "mapping",
|
|
748
|
-
range
|
|
749
|
-
};
|
|
750
|
-
}
|
|
751
|
-
diagnostics.add({
|
|
752
|
-
code: "MOLDEA_YAML_MALFORMED",
|
|
753
|
-
details: { reason: "node-type" },
|
|
754
|
-
path,
|
|
755
|
-
range
|
|
756
|
-
});
|
|
757
|
-
return null;
|
|
758
|
-
};
|
|
759
|
-
var addParserDiagnostic = (code, start, end, path, locator, diagnostics) => {
|
|
760
|
-
if (code === "BAD_DIRECTIVE") return;
|
|
761
|
-
if (code === "DUPLICATE_KEY") {
|
|
762
|
-
diagnostics.add({
|
|
763
|
-
code: "MOLDEA_YAML_DUPLICATE_KEY",
|
|
764
|
-
path,
|
|
765
|
-
range: locator.locateRange(start, end)
|
|
766
|
-
});
|
|
767
|
-
return;
|
|
768
|
-
}
|
|
769
|
-
if (code === "TAG_RESOLVE_FAILED") return;
|
|
770
|
-
diagnostics.add({
|
|
771
|
-
code: "MOLDEA_YAML_MALFORMED",
|
|
772
|
-
details: { reason: code === "RESOURCE_EXHAUSTION" ? "resource-exhaustion" : "syntax" },
|
|
773
|
-
path,
|
|
774
|
-
range: locator.locateRange(start, end)
|
|
775
|
-
});
|
|
776
|
-
};
|
|
777
|
-
/**
|
|
778
|
-
* Parses one normalized YAML 1.2 Core Schema document into parser-neutral nodes.
|
|
779
|
-
* @param value The normalized manifest text.
|
|
780
|
-
* @param path The logical source path used by diagnostics.
|
|
781
|
-
* @param locator The scalar-aware source locator for the normalized text.
|
|
782
|
-
* @param diagnostics The operation diagnostic collector.
|
|
783
|
-
* @returns The private parsed tree only when the YAML substrate is trustworthy.
|
|
784
|
-
*/
|
|
785
|
-
var parseStrictYaml = (value, path, locator, diagnostics) => {
|
|
786
|
-
const initialDiagnosticCount = diagnostics.size;
|
|
787
|
-
for (const token of new Parser().parse(value)) if (token.type === "directive") addUnsupportedFeature(diagnostics, path, locator.locateRange(token.offset, token.offset + token.source.length), "directive");
|
|
788
|
-
const documents = parseAllDocuments(value, {
|
|
789
|
-
intAsBigInt: true,
|
|
790
|
-
keepSourceTokens: true,
|
|
791
|
-
logLevel: "silent",
|
|
792
|
-
merge: false,
|
|
793
|
-
prettyErrors: false,
|
|
794
|
-
resolveKnownTags: false,
|
|
795
|
-
schema: "core",
|
|
796
|
-
strict: true,
|
|
797
|
-
uniqueKeys: true,
|
|
798
|
-
version: "1.2"
|
|
799
|
-
});
|
|
800
|
-
if (documents.length > 1) {
|
|
801
|
-
const range = documents[1]?.range;
|
|
802
|
-
diagnostics.add({
|
|
803
|
-
code: "MOLDEA_YAML_MULTIPLE_DOCUMENTS",
|
|
804
|
-
path,
|
|
805
|
-
range: locator.locateRange(range?.[0] ?? 0, range?.[0] ?? 0)
|
|
806
|
-
});
|
|
807
|
-
}
|
|
808
|
-
for (const document of documents) for (const error of [...document.errors, ...document.warnings]) addParserDiagnostic(error.code, error.pos[0], error.pos[1], path, locator, diagnostics);
|
|
809
|
-
if (documents.length > 1 || diagnostics.size > initialDiagnosticCount) return {
|
|
810
|
-
valid: false,
|
|
811
|
-
value: null
|
|
812
|
-
};
|
|
813
|
-
const document = documents[0];
|
|
814
|
-
if (document === void 0 || document.contents === null) return {
|
|
815
|
-
valid: true,
|
|
816
|
-
value: {
|
|
817
|
-
kind: "scalar",
|
|
818
|
-
range: locator.locateRange(0, 0),
|
|
819
|
-
source: "",
|
|
820
|
-
style: null,
|
|
821
|
-
value: null
|
|
822
|
-
}
|
|
823
|
-
};
|
|
824
|
-
const parsedValue = convertNode(document.contents, path, locator, diagnostics);
|
|
825
|
-
return {
|
|
826
|
-
valid: parsedValue !== null && diagnostics.size === initialDiagnosticCount,
|
|
827
|
-
value: diagnostics.size === initialDiagnosticCount ? parsedValue : null
|
|
828
|
-
};
|
|
829
|
-
};
|
|
830
|
-
//#endregion
|
|
831
341
|
//#region src/decision/index.ts
|
|
832
342
|
/**
|
|
833
343
|
* Parses and validates one complete decision document without resolving cross-file relationships.
|
|
834
344
|
* @param input The canonical logical path and exact decision text or bytes.
|
|
835
|
-
* @param options The immutable Core
|
|
345
|
+
* @param options The immutable Core limit snapshot.
|
|
836
346
|
* @param operation The owning public or repository-level operation for typed failures.
|
|
837
347
|
* @returns A frozen all-or-nothing decision parse result.
|
|
838
348
|
* @throws
|
|
@@ -897,846 +407,13 @@ var parseDecisionDocument = async (input, options, operation = "parse-decision")
|
|
|
897
407
|
});
|
|
898
408
|
};
|
|
899
409
|
//#endregion
|
|
900
|
-
//#region src/
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
details: { reason },
|
|
908
|
-
entity,
|
|
909
|
-
path: context.path,
|
|
910
|
-
pointer,
|
|
911
|
-
range
|
|
912
|
-
});
|
|
913
|
-
};
|
|
914
|
-
var readMapping = (node, pointer, allowedProperties, context, entity = null) => {
|
|
915
|
-
if (node.kind !== "mapping") {
|
|
916
|
-
addInvalidValue(context, pointer, node.range, "mapping-required", entity);
|
|
917
|
-
return null;
|
|
918
|
-
}
|
|
919
|
-
const entries = /* @__PURE__ */ new Map();
|
|
920
|
-
for (const entry of node.entries) {
|
|
921
|
-
if (entry.key.kind !== "scalar" || typeof entry.key.value !== "string") {
|
|
922
|
-
addInvalidValue(context, pointer, entry.key.range, "string-key-required", entity);
|
|
923
|
-
continue;
|
|
924
|
-
}
|
|
925
|
-
const key = entry.key.value;
|
|
926
|
-
if (allowedProperties !== null && !allowedProperties.has(key)) {
|
|
927
|
-
context.diagnostics.add({
|
|
928
|
-
code: "MOLDEA_MANIFEST_PROPERTY_UNKNOWN",
|
|
929
|
-
entity,
|
|
930
|
-
path: context.path,
|
|
931
|
-
pointer: childPointer$2(pointer, key),
|
|
932
|
-
range: entry.key.range
|
|
933
|
-
});
|
|
934
|
-
continue;
|
|
935
|
-
}
|
|
936
|
-
entries.set(key, {
|
|
937
|
-
key: entry.key,
|
|
938
|
-
value: entry.value
|
|
939
|
-
});
|
|
940
|
-
}
|
|
941
|
-
return entries;
|
|
942
|
-
};
|
|
943
|
-
var readString = (entry, pointer, context, options = {}) => {
|
|
944
|
-
if (entry === void 0) {
|
|
945
|
-
if (options.required === true) addInvalidValue(context, pointer, null, "required", options.entity ?? null);
|
|
946
|
-
return null;
|
|
947
|
-
}
|
|
948
|
-
if (entry.value.kind !== "scalar" || typeof entry.value.value !== "string") {
|
|
949
|
-
addInvalidValue(context, pointer, entry.value.range, "string-required", options.entity ?? null);
|
|
950
|
-
return null;
|
|
951
|
-
}
|
|
952
|
-
const value = entry.value.value;
|
|
953
|
-
if (!hasNonWhitespace(value) || options.singleLine === true && !isNonEmptySingleLine(value)) {
|
|
954
|
-
addInvalidValue(context, pointer, entry.value.range, "string-invalid", options.entity ?? null);
|
|
955
|
-
return null;
|
|
956
|
-
}
|
|
957
|
-
return value;
|
|
958
|
-
};
|
|
959
|
-
var validateStableId = (value, range, pointer, context, entity = null) => {
|
|
960
|
-
if (!isStableId(value)) {
|
|
961
|
-
context.diagnostics.add({
|
|
962
|
-
code: "MOLDEA_ID_INVALID",
|
|
963
|
-
entity,
|
|
964
|
-
path: context.path,
|
|
965
|
-
pointer,
|
|
966
|
-
range
|
|
967
|
-
});
|
|
968
|
-
return false;
|
|
969
|
-
}
|
|
970
|
-
if (isReservedId(value)) {
|
|
971
|
-
context.diagnostics.add({
|
|
972
|
-
code: "MOLDEA_ID_RESERVED",
|
|
973
|
-
entity,
|
|
974
|
-
path: context.path,
|
|
975
|
-
pointer,
|
|
976
|
-
range
|
|
977
|
-
});
|
|
978
|
-
return false;
|
|
979
|
-
}
|
|
980
|
-
return true;
|
|
981
|
-
};
|
|
982
|
-
var readReference = (node, pointer, context, entity = null) => {
|
|
983
|
-
const entries = readMapping(node, pointer, /* @__PURE__ */ new Set(["path", "symbol"]), context, entity);
|
|
984
|
-
if (entries === null) return null;
|
|
985
|
-
const pathEntry = entries.get("path");
|
|
986
|
-
if (pathEntry?.value.kind !== "scalar" || typeof pathEntry.value.value !== "string") {
|
|
987
|
-
context.diagnostics.add({
|
|
988
|
-
code: "MOLDEA_PATH_INVALID",
|
|
989
|
-
details: { reason: pathEntry === void 0 ? "missing" : "type" },
|
|
990
|
-
entity,
|
|
991
|
-
path: context.path,
|
|
992
|
-
pointer: childPointer$2(pointer, "path"),
|
|
993
|
-
range: pathEntry?.value.range ?? null
|
|
994
|
-
});
|
|
995
|
-
return null;
|
|
996
|
-
}
|
|
997
|
-
const path = parseManifestPath(pathEntry.value.value);
|
|
998
|
-
if (path === null) {
|
|
999
|
-
context.diagnostics.add({
|
|
1000
|
-
code: "MOLDEA_PATH_INVALID",
|
|
1001
|
-
entity,
|
|
1002
|
-
path: context.path,
|
|
1003
|
-
pointer: childPointer$2(pointer, "path"),
|
|
1004
|
-
range: pathEntry.value.range
|
|
1005
|
-
});
|
|
1006
|
-
return null;
|
|
1007
|
-
}
|
|
1008
|
-
const symbolEntry = entries.get("symbol");
|
|
1009
|
-
if (symbolEntry === void 0) return { path };
|
|
1010
|
-
if (symbolEntry.value.kind !== "scalar" || typeof symbolEntry.value.value !== "string" || !isRepositorySymbol(symbolEntry.value.value)) {
|
|
1011
|
-
context.diagnostics.add({
|
|
1012
|
-
code: "MOLDEA_SYMBOL_INVALID",
|
|
1013
|
-
entity,
|
|
1014
|
-
path: context.path,
|
|
1015
|
-
pointer: childPointer$2(pointer, "symbol"),
|
|
1016
|
-
range: symbolEntry.value.range
|
|
1017
|
-
});
|
|
1018
|
-
return null;
|
|
1019
|
-
}
|
|
1020
|
-
if (isCanonicalMoldeaPath(path)) {
|
|
1021
|
-
context.diagnostics.add({
|
|
1022
|
-
code: "MOLDEA_SYMBOL_FORBIDDEN",
|
|
1023
|
-
entity,
|
|
1024
|
-
path: context.path,
|
|
1025
|
-
pointer: childPointer$2(pointer, "symbol"),
|
|
1026
|
-
range: symbolEntry.value.range
|
|
1027
|
-
});
|
|
1028
|
-
return null;
|
|
1029
|
-
}
|
|
1030
|
-
return {
|
|
1031
|
-
path,
|
|
1032
|
-
symbol: symbolEntry.value.value
|
|
1033
|
-
};
|
|
1034
|
-
};
|
|
1035
|
-
var readReferenceList = (node, pointer, context, entity = null) => {
|
|
1036
|
-
if (node.kind !== "sequence" || node.items.length === 0) {
|
|
1037
|
-
addInvalidValue(context, pointer, node.range, "non-empty-sequence-required", entity);
|
|
1038
|
-
return [];
|
|
1039
|
-
}
|
|
1040
|
-
const references = [];
|
|
1041
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1042
|
-
node.items.forEach((item, index) => {
|
|
1043
|
-
const reference = readReference(item, childPointer$2(pointer, String(index)), context, entity);
|
|
1044
|
-
if (reference === null) return;
|
|
1045
|
-
const key = `${reference.path}\0${reference.symbol ?? ""}`;
|
|
1046
|
-
if (seen.has(key)) {
|
|
1047
|
-
context.diagnostics.add({
|
|
1048
|
-
code: "MOLDEA_PATH_DUPLICATE",
|
|
1049
|
-
entity,
|
|
1050
|
-
path: context.path,
|
|
1051
|
-
pointer: childPointer$2(pointer, String(index)),
|
|
1052
|
-
range: item.range
|
|
1053
|
-
});
|
|
1054
|
-
return;
|
|
1055
|
-
}
|
|
1056
|
-
seen.add(key);
|
|
1057
|
-
references.push(reference);
|
|
1058
|
-
});
|
|
1059
|
-
return sortRepositoryReferences(references);
|
|
1060
|
-
};
|
|
1061
|
-
var readAffectedBy = (node, pointer, context, entity = null) => {
|
|
1062
|
-
if (node.kind !== "sequence" || node.items.length === 0) {
|
|
1063
|
-
addInvalidValue(context, pointer, node.range, "non-empty-sequence-required", entity);
|
|
1064
|
-
return [];
|
|
1065
|
-
}
|
|
1066
|
-
const values = [];
|
|
1067
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1068
|
-
node.items.forEach((item, index) => {
|
|
1069
|
-
const itemPointer = childPointer$2(pointer, String(index));
|
|
1070
|
-
if (item.kind !== "scalar" || typeof item.value !== "string") {
|
|
1071
|
-
addInvalidValue(context, itemPointer, item.range, "string-required", entity);
|
|
1072
|
-
return;
|
|
1073
|
-
}
|
|
1074
|
-
const isGlob = item.value.includes("*") || hasUnsupportedGlobMetacharacter(item.value);
|
|
1075
|
-
if (!(isGlob ? isSimpleGlob(item.value) : parseManifestPath(item.value) !== null)) {
|
|
1076
|
-
context.diagnostics.add({
|
|
1077
|
-
code: isGlob ? "MOLDEA_GLOB_INVALID" : "MOLDEA_PATH_INVALID",
|
|
1078
|
-
entity,
|
|
1079
|
-
path: context.path,
|
|
1080
|
-
pointer: itemPointer,
|
|
1081
|
-
range: item.range
|
|
1082
|
-
});
|
|
1083
|
-
return;
|
|
1084
|
-
}
|
|
1085
|
-
if (seen.has(item.value)) {
|
|
1086
|
-
context.diagnostics.add({
|
|
1087
|
-
code: isGlob ? "MOLDEA_PATTERN_DUPLICATE" : "MOLDEA_PATH_DUPLICATE",
|
|
1088
|
-
entity,
|
|
1089
|
-
path: context.path,
|
|
1090
|
-
pointer: itemPointer,
|
|
1091
|
-
range: item.range
|
|
1092
|
-
});
|
|
1093
|
-
return;
|
|
1094
|
-
}
|
|
1095
|
-
seen.add(item.value);
|
|
1096
|
-
values.push(item.value);
|
|
1097
|
-
});
|
|
1098
|
-
return values.sort(compareExactStrings);
|
|
1099
|
-
};
|
|
1100
|
-
var readRelationship = (node, pointer, context) => {
|
|
1101
|
-
const entries = readMapping(node, pointer, /* @__PURE__ */ new Set(["affectedBy", "bindings"]), context);
|
|
1102
|
-
if (entries === null) return null;
|
|
1103
|
-
const bindingsEntry = entries.get("bindings");
|
|
1104
|
-
const affectedByEntry = entries.get("affectedBy");
|
|
1105
|
-
if (bindingsEntry === void 0 && affectedByEntry === void 0) context.diagnostics.add({
|
|
1106
|
-
code: "MOLDEA_CONTEXT_RELATIONSHIP_EMPTY",
|
|
1107
|
-
path: context.path,
|
|
1108
|
-
pointer,
|
|
1109
|
-
range: node.range
|
|
1110
|
-
});
|
|
1111
|
-
return {
|
|
1112
|
-
...bindingsEntry === void 0 ? {} : { bindings: readReferenceList(bindingsEntry.value, childPointer$2(pointer, "bindings"), context) },
|
|
1113
|
-
...affectedByEntry === void 0 ? {} : { affectedBy: readAffectedBy(affectedByEntry.value, childPointer$2(pointer, "affectedBy"), context) }
|
|
1114
|
-
};
|
|
1115
|
-
};
|
|
1116
|
-
var readRelationshipRecord = (node, pointer, kind, context) => {
|
|
1117
|
-
const entries = readMapping(node, pointer, null, context);
|
|
1118
|
-
if (entries === null) return null;
|
|
1119
|
-
const normalized = [];
|
|
1120
|
-
for (const [key, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
1121
|
-
const path = parseManifestPath(key);
|
|
1122
|
-
if (!(path !== null && (kind === "context" ? isContextPath(path, true) : isDecisionPath(path)))) {
|
|
1123
|
-
context.diagnostics.add({
|
|
1124
|
-
code: kind === "context" ? "MOLDEA_CONTEXT_PATH_INVALID" : "MOLDEA_DECISION_FILENAME_INVALID",
|
|
1125
|
-
path: context.path,
|
|
1126
|
-
pointer: childPointer$2(pointer, key),
|
|
1127
|
-
range: entry.key.range
|
|
1128
|
-
});
|
|
1129
|
-
continue;
|
|
1130
|
-
}
|
|
1131
|
-
const relationship = readRelationship(entry.value, childPointer$2(pointer, key), context);
|
|
1132
|
-
if (relationship !== null) normalized.push([key, relationship]);
|
|
1133
|
-
}
|
|
1134
|
-
return createNullPrototypeRecord(normalized);
|
|
1135
|
-
};
|
|
1136
|
-
var readPathList = (node, pointer, kind, context, entity) => {
|
|
1137
|
-
if (node.kind !== "sequence") {
|
|
1138
|
-
addInvalidValue(context, pointer, node.range, "sequence-required", entity);
|
|
1139
|
-
return [];
|
|
1140
|
-
}
|
|
1141
|
-
const paths = [];
|
|
1142
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1143
|
-
node.items.forEach((item, index) => {
|
|
1144
|
-
const itemPointer = childPointer$2(pointer, String(index));
|
|
1145
|
-
if (item.kind !== "scalar" || typeof item.value !== "string") {
|
|
1146
|
-
addInvalidValue(context, itemPointer, item.range, "string-required", entity);
|
|
1147
|
-
return;
|
|
1148
|
-
}
|
|
1149
|
-
const path = parseManifestPath(item.value);
|
|
1150
|
-
if (!(path !== null && (kind === "context" ? isContextPath(path, false) : kind === "decision" ? isDecisionPath(path) : isMirrorPath(path))) || path === null) {
|
|
1151
|
-
const code = kind === "context" ? "MOLDEA_CONTEXT_PATH_INVALID" : kind === "decision" ? "MOLDEA_DECISION_FILENAME_INVALID" : path !== null && !isMirrorPath(path) ? "MOLDEA_MIRROR_PATH_INSIDE_MOLDEA" : "MOLDEA_MIRROR_PATH_INVALID";
|
|
1152
|
-
context.diagnostics.add({
|
|
1153
|
-
code,
|
|
1154
|
-
entity,
|
|
1155
|
-
path: context.path,
|
|
1156
|
-
pointer: itemPointer,
|
|
1157
|
-
range: item.range
|
|
1158
|
-
});
|
|
1159
|
-
return;
|
|
1160
|
-
}
|
|
1161
|
-
if (seen.has(path)) {
|
|
1162
|
-
context.diagnostics.add({
|
|
1163
|
-
code: kind === "mirror" ? "MOLDEA_MIRROR_PATH_DUPLICATE" : "MOLDEA_PATH_DUPLICATE",
|
|
1164
|
-
entity,
|
|
1165
|
-
path: context.path,
|
|
1166
|
-
pointer: itemPointer,
|
|
1167
|
-
range: item.range
|
|
1168
|
-
});
|
|
1169
|
-
return;
|
|
1170
|
-
}
|
|
1171
|
-
if (kind === "mirror" && context.mirrorPaths.has(path)) {
|
|
1172
|
-
context.diagnostics.add({
|
|
1173
|
-
code: "MOLDEA_MIRROR_PATH_DUPLICATE",
|
|
1174
|
-
entity,
|
|
1175
|
-
path: context.path,
|
|
1176
|
-
pointer: itemPointer,
|
|
1177
|
-
range: item.range
|
|
1178
|
-
});
|
|
1179
|
-
return;
|
|
1180
|
-
}
|
|
1181
|
-
seen.add(path);
|
|
1182
|
-
if (kind === "mirror") context.mirrorPaths.add(path);
|
|
1183
|
-
paths.push(path);
|
|
1184
|
-
});
|
|
1185
|
-
return paths.sort(compareExactStrings);
|
|
1186
|
-
};
|
|
1187
|
-
var readRuntime = (node, pointer, context, agentId) => {
|
|
1188
|
-
const entity = { agentId };
|
|
1189
|
-
const entries = readMapping(node, pointer, /* @__PURE__ */ new Set(["guidance", "id"]), context, entity);
|
|
1190
|
-
if (entries === null) return null;
|
|
1191
|
-
const idEntry = entries.get("id");
|
|
1192
|
-
if (idEntry?.value.kind !== "scalar" || typeof idEntry.value.value !== "string") {
|
|
1193
|
-
context.diagnostics.add({
|
|
1194
|
-
code: "MOLDEA_RUNTIME_ID_INVALID",
|
|
1195
|
-
entity,
|
|
1196
|
-
path: context.path,
|
|
1197
|
-
pointer: childPointer$2(pointer, "id"),
|
|
1198
|
-
range: idEntry?.value.range ?? null
|
|
1199
|
-
});
|
|
1200
|
-
return null;
|
|
1201
|
-
}
|
|
1202
|
-
const id = idEntry.value.value;
|
|
1203
|
-
if (!isStableId(id) || isReservedId(id) || !RECOGNIZED_RUNTIME_ADAPTER_IDS.includes(id)) context.diagnostics.add({
|
|
1204
|
-
code: "MOLDEA_RUNTIME_ID_INVALID",
|
|
1205
|
-
entity,
|
|
1206
|
-
path: context.path,
|
|
1207
|
-
pointer: childPointer$2(pointer, "id"),
|
|
1208
|
-
range: idEntry.value.range
|
|
1209
|
-
});
|
|
1210
|
-
else context.runtimeLocations.push({
|
|
1211
|
-
adapterId: id,
|
|
1212
|
-
agentId,
|
|
1213
|
-
path: context.path,
|
|
1214
|
-
pointer: childPointer$2(pointer, "id"),
|
|
1215
|
-
range: idEntry.value.range
|
|
1216
|
-
});
|
|
1217
|
-
const guidanceEntry = entries.get("guidance");
|
|
1218
|
-
let guidance = null;
|
|
1219
|
-
if (guidanceEntry !== void 0) {
|
|
1220
|
-
if (guidanceEntry.value.kind === "scalar" && typeof guidanceEntry.value.value === "string") {
|
|
1221
|
-
const candidate = parseManifestPath(guidanceEntry.value.value);
|
|
1222
|
-
if (candidate !== null && isRuntimeGuidancePath(candidate)) guidance = candidate;
|
|
1223
|
-
else context.diagnostics.add({
|
|
1224
|
-
code: "MOLDEA_PATH_INVALID",
|
|
1225
|
-
details: { reason: "runtime-guidance" },
|
|
1226
|
-
entity,
|
|
1227
|
-
path: context.path,
|
|
1228
|
-
pointer: childPointer$2(pointer, "guidance"),
|
|
1229
|
-
range: guidanceEntry.value.range
|
|
1230
|
-
});
|
|
1231
|
-
} else context.diagnostics.add({
|
|
1232
|
-
code: "MOLDEA_PATH_INVALID",
|
|
1233
|
-
details: { reason: "runtime-guidance" },
|
|
1234
|
-
entity,
|
|
1235
|
-
path: context.path,
|
|
1236
|
-
pointer: childPointer$2(pointer, "guidance"),
|
|
1237
|
-
range: guidanceEntry.value.range
|
|
1238
|
-
});
|
|
1239
|
-
}
|
|
1240
|
-
return {
|
|
1241
|
-
id,
|
|
1242
|
-
...guidance === null ? {} : { guidance }
|
|
1243
|
-
};
|
|
1244
|
-
};
|
|
1245
|
-
var readVariables = (node, pointer, context, agentId) => {
|
|
1246
|
-
const entries = readMapping(node, pointer, null, context, { agentId });
|
|
1247
|
-
if (entries === null) return null;
|
|
1248
|
-
const normalized = [];
|
|
1249
|
-
for (const [variableId, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
1250
|
-
const entity = {
|
|
1251
|
-
agentId,
|
|
1252
|
-
variableId
|
|
1253
|
-
};
|
|
1254
|
-
if (!isVariableId(variableId)) context.diagnostics.add({
|
|
1255
|
-
code: "MOLDEA_VARIABLE_ID_INVALID",
|
|
1256
|
-
entity,
|
|
1257
|
-
path: context.path,
|
|
1258
|
-
pointer: childPointer$2(pointer, variableId),
|
|
1259
|
-
range: entry.key.range
|
|
1260
|
-
});
|
|
1261
|
-
const variablePointer = childPointer$2(pointer, variableId);
|
|
1262
|
-
const variableEntries = readMapping(entry.value, variablePointer, /* @__PURE__ */ new Set(["description"]), context, entity);
|
|
1263
|
-
if (variableEntries === null) continue;
|
|
1264
|
-
const description = readString(variableEntries.get("description"), childPointer$2(variablePointer, "description"), context, {
|
|
1265
|
-
entity,
|
|
1266
|
-
required: true
|
|
1267
|
-
});
|
|
1268
|
-
if (description !== null) normalized.push([variableId, { description }]);
|
|
1269
|
-
}
|
|
1270
|
-
return createNullPrototypeRecord(normalized);
|
|
1271
|
-
};
|
|
1272
|
-
var readBindings = (node, pointer, context, agentId, declaredVariables) => {
|
|
1273
|
-
const entity = { agentId };
|
|
1274
|
-
const entries = readMapping(node, pointer, /* @__PURE__ */ new Set([
|
|
1275
|
-
"inputSchema",
|
|
1276
|
-
"instructionLoader",
|
|
1277
|
-
"outputSchema",
|
|
1278
|
-
"runtimeAgent",
|
|
1279
|
-
"variableProviders"
|
|
1280
|
-
]), context, entity);
|
|
1281
|
-
if (entries === null) return null;
|
|
1282
|
-
const referenceProperty = (key) => {
|
|
1283
|
-
const entry = entries.get(key);
|
|
1284
|
-
return entry === void 0 ? null : readReference(entry.value, childPointer$2(pointer, key), context, entity);
|
|
1285
|
-
};
|
|
1286
|
-
const inputSchema = referenceProperty("inputSchema");
|
|
1287
|
-
const instructionLoader = referenceProperty("instructionLoader");
|
|
1288
|
-
const outputSchema = referenceProperty("outputSchema");
|
|
1289
|
-
const runtimeAgent = referenceProperty("runtimeAgent");
|
|
1290
|
-
const providersEntry = entries.get("variableProviders");
|
|
1291
|
-
let variableProviders = null;
|
|
1292
|
-
if (providersEntry !== void 0) {
|
|
1293
|
-
const providers = readMapping(providersEntry.value, childPointer$2(pointer, "variableProviders"), null, context, entity);
|
|
1294
|
-
if (providers !== null) {
|
|
1295
|
-
const normalized = [];
|
|
1296
|
-
for (const [variableId, providerEntry] of [...providers].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
1297
|
-
const variableEntity = {
|
|
1298
|
-
agentId,
|
|
1299
|
-
variableId
|
|
1300
|
-
};
|
|
1301
|
-
const providerPointer = childPointer$2(childPointer$2(pointer, "variableProviders"), variableId);
|
|
1302
|
-
if (!isVariableId(variableId)) context.diagnostics.add({
|
|
1303
|
-
code: "MOLDEA_VARIABLE_ID_INVALID",
|
|
1304
|
-
entity: variableEntity,
|
|
1305
|
-
path: context.path,
|
|
1306
|
-
pointer: providerPointer,
|
|
1307
|
-
range: providerEntry.key.range
|
|
1308
|
-
});
|
|
1309
|
-
else if (!declaredVariables.has(variableId)) context.diagnostics.add({
|
|
1310
|
-
code: "MOLDEA_VARIABLE_PROVIDER_UNDECLARED",
|
|
1311
|
-
entity: variableEntity,
|
|
1312
|
-
path: context.path,
|
|
1313
|
-
pointer: providerPointer,
|
|
1314
|
-
range: providerEntry.key.range
|
|
1315
|
-
});
|
|
1316
|
-
const reference = readReference(providerEntry.value, providerPointer, context, variableEntity);
|
|
1317
|
-
if (reference !== null) normalized.push([variableId, reference]);
|
|
1318
|
-
}
|
|
1319
|
-
variableProviders = createNullPrototypeRecord(normalized);
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1322
|
-
return {
|
|
1323
|
-
...runtimeAgent === null ? {} : { runtimeAgent },
|
|
1324
|
-
...inputSchema === null ? {} : { inputSchema },
|
|
1325
|
-
...outputSchema === null ? {} : { outputSchema },
|
|
1326
|
-
...instructionLoader === null ? {} : { instructionLoader },
|
|
1327
|
-
...variableProviders === null ? {} : { variableProviders }
|
|
1328
|
-
};
|
|
1329
|
-
};
|
|
1330
|
-
var readCapability$1 = (node, pointer, context, agentId, capabilityId, kind) => {
|
|
1331
|
-
const entity = {
|
|
1332
|
-
agentId,
|
|
1333
|
-
capabilityId,
|
|
1334
|
-
capabilityKind: kind
|
|
1335
|
-
};
|
|
1336
|
-
const entries = readMapping(node, pointer, kind === "tool" ? /* @__PURE__ */ new Set([
|
|
1337
|
-
"affectedBy",
|
|
1338
|
-
"description",
|
|
1339
|
-
"implementation",
|
|
1340
|
-
"inputSchema",
|
|
1341
|
-
"name",
|
|
1342
|
-
"outputSchema",
|
|
1343
|
-
"registration"
|
|
1344
|
-
]) : /* @__PURE__ */ new Set([
|
|
1345
|
-
"affectedBy",
|
|
1346
|
-
"description",
|
|
1347
|
-
"implementation",
|
|
1348
|
-
"name",
|
|
1349
|
-
"registration"
|
|
1350
|
-
]), context, entity);
|
|
1351
|
-
if (entries === null) return null;
|
|
1352
|
-
const name = readString(entries.get("name"), childPointer$2(pointer, "name"), context, {
|
|
1353
|
-
entity,
|
|
1354
|
-
required: true,
|
|
1355
|
-
singleLine: true
|
|
1356
|
-
});
|
|
1357
|
-
const descriptionEntry = entries.get("description");
|
|
1358
|
-
let description = null;
|
|
1359
|
-
if (descriptionEntry === void 0) context.diagnostics.add({
|
|
1360
|
-
code: "MOLDEA_CAPABILITY_DESCRIPTION_MISSING",
|
|
1361
|
-
entity,
|
|
1362
|
-
path: context.path,
|
|
1363
|
-
pointer: childPointer$2(pointer, "description")
|
|
1364
|
-
});
|
|
1365
|
-
else if (descriptionEntry.value.kind !== "scalar" || typeof descriptionEntry.value.value !== "string" || !isCapabilityDescription(descriptionEntry.value.value)) context.diagnostics.add({
|
|
1366
|
-
code: "MOLDEA_CAPABILITY_DESCRIPTION_INVALID",
|
|
1367
|
-
entity,
|
|
1368
|
-
path: context.path,
|
|
1369
|
-
pointer: childPointer$2(pointer, "description"),
|
|
1370
|
-
range: descriptionEntry.value.range
|
|
1371
|
-
});
|
|
1372
|
-
else description = descriptionEntry.value.value;
|
|
1373
|
-
const implementationEntry = entries.get("implementation");
|
|
1374
|
-
let implementation = null;
|
|
1375
|
-
if (implementationEntry === void 0) context.diagnostics.add({
|
|
1376
|
-
code: kind === "tool" ? "MOLDEA_TOOL_IMPLEMENTATION_MISSING" : "MOLDEA_SKILL_IMPLEMENTATION_MISSING",
|
|
1377
|
-
entity,
|
|
1378
|
-
path: context.path,
|
|
1379
|
-
pointer: childPointer$2(pointer, "implementation")
|
|
1380
|
-
});
|
|
1381
|
-
else implementation = readReference(implementationEntry.value, childPointer$2(pointer, "implementation"), context, entity);
|
|
1382
|
-
const optionalReference = (key) => {
|
|
1383
|
-
const entry = entries.get(key);
|
|
1384
|
-
return entry === void 0 ? null : readReference(entry.value, childPointer$2(pointer, key), context, entity);
|
|
1385
|
-
};
|
|
1386
|
-
const registration = optionalReference("registration");
|
|
1387
|
-
const inputSchema = kind === "tool" ? optionalReference("inputSchema") : null;
|
|
1388
|
-
const outputSchema = kind === "tool" ? optionalReference("outputSchema") : null;
|
|
1389
|
-
const affectedByEntry = entries.get("affectedBy");
|
|
1390
|
-
const affectedBy = affectedByEntry === void 0 ? null : readAffectedBy(affectedByEntry.value, childPointer$2(pointer, "affectedBy"), context, entity);
|
|
1391
|
-
if (name === null || description === null || implementation === null) return null;
|
|
1392
|
-
return {
|
|
1393
|
-
name,
|
|
1394
|
-
description,
|
|
1395
|
-
implementation,
|
|
1396
|
-
...registration === null ? {} : { registration },
|
|
1397
|
-
...inputSchema === null ? {} : { inputSchema },
|
|
1398
|
-
...outputSchema === null ? {} : { outputSchema },
|
|
1399
|
-
...affectedBy === null ? {} : { affectedBy }
|
|
1400
|
-
};
|
|
1401
|
-
};
|
|
1402
|
-
var readCapabilities = (node, pointer, context, agentId, kind) => {
|
|
1403
|
-
const entries = readMapping(node, pointer, null, context, { agentId });
|
|
1404
|
-
if (entries === null) return null;
|
|
1405
|
-
const normalized = [];
|
|
1406
|
-
for (const [capabilityId, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
1407
|
-
const entity = {
|
|
1408
|
-
agentId,
|
|
1409
|
-
capabilityId,
|
|
1410
|
-
capabilityKind: kind
|
|
1411
|
-
};
|
|
1412
|
-
const capabilityPointer = childPointer$2(pointer, capabilityId);
|
|
1413
|
-
validateStableId(capabilityId, entry.key.range, capabilityPointer, context, entity);
|
|
1414
|
-
const capability = readCapability$1(entry.value, capabilityPointer, context, agentId, capabilityId, kind);
|
|
1415
|
-
if (capability !== null) normalized.push([capabilityId, capability]);
|
|
1416
|
-
}
|
|
1417
|
-
return createNullPrototypeRecord(normalized);
|
|
1418
|
-
};
|
|
1419
|
-
var readUnresolved = (node, pointer, context, agentId) => {
|
|
1420
|
-
const entries = readMapping(node, pointer, null, context, agentId === void 0 ? null : { agentId });
|
|
1421
|
-
if (entries === null) return null;
|
|
1422
|
-
const normalized = [];
|
|
1423
|
-
for (const [requirementId, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
1424
|
-
const entity = agentId === void 0 ? null : { agentId };
|
|
1425
|
-
const requirementPointer = childPointer$2(pointer, requirementId);
|
|
1426
|
-
validateStableId(requirementId, entry.key.range, requirementPointer, context, entity);
|
|
1427
|
-
const requirementEntries = readMapping(entry.value, requirementPointer, /* @__PURE__ */ new Set([
|
|
1428
|
-
"category",
|
|
1429
|
-
"description",
|
|
1430
|
-
"effect",
|
|
1431
|
-
"reference",
|
|
1432
|
-
"related",
|
|
1433
|
-
"resolution"
|
|
1434
|
-
]), context, entity);
|
|
1435
|
-
if (requirementEntries === null) continue;
|
|
1436
|
-
const category = readString(requirementEntries.get("category"), childPointer$2(requirementPointer, "category"), context, {
|
|
1437
|
-
...entity === null ? {} : { entity },
|
|
1438
|
-
required: true
|
|
1439
|
-
});
|
|
1440
|
-
if (category !== null && !isStableId(category)) context.diagnostics.add({
|
|
1441
|
-
code: "MOLDEA_ID_INVALID",
|
|
1442
|
-
entity,
|
|
1443
|
-
path: context.path,
|
|
1444
|
-
pointer: childPointer$2(requirementPointer, "category"),
|
|
1445
|
-
range: requirementEntries.get("category")?.value.range ?? null
|
|
1446
|
-
});
|
|
1447
|
-
const effectEntry = requirementEntries.get("effect");
|
|
1448
|
-
let effect = null;
|
|
1449
|
-
if (effectEntry?.value.kind === "scalar" && (effectEntry.value.value === "blocking" || effectEntry.value.value === "warning" || effectEntry.value.value === "informational")) effect = effectEntry.value.value;
|
|
1450
|
-
else addInvalidValue(context, childPointer$2(requirementPointer, "effect"), effectEntry?.value.range ?? null, effectEntry === void 0 ? "required" : "enum", entity);
|
|
1451
|
-
const description = readString(requirementEntries.get("description"), childPointer$2(requirementPointer, "description"), context, {
|
|
1452
|
-
...entity === null ? {} : { entity },
|
|
1453
|
-
required: true
|
|
1454
|
-
});
|
|
1455
|
-
const resolution = readString(requirementEntries.get("resolution"), childPointer$2(requirementPointer, "resolution"), context, {
|
|
1456
|
-
...entity === null ? {} : { entity },
|
|
1457
|
-
required: true
|
|
1458
|
-
});
|
|
1459
|
-
const relatedEntry = requirementEntries.get("related");
|
|
1460
|
-
const related = relatedEntry === void 0 ? null : readReferenceList(relatedEntry.value, childPointer$2(requirementPointer, "related"), context, entity);
|
|
1461
|
-
const reference = readString(requirementEntries.get("reference"), childPointer$2(requirementPointer, "reference"), context, {
|
|
1462
|
-
...entity === null ? {} : { entity },
|
|
1463
|
-
singleLine: true
|
|
1464
|
-
});
|
|
1465
|
-
if (category !== null && effect !== null && description !== null && resolution !== null) normalized.push([requirementId, {
|
|
1466
|
-
category,
|
|
1467
|
-
effect,
|
|
1468
|
-
description,
|
|
1469
|
-
resolution,
|
|
1470
|
-
...related === null ? {} : { related },
|
|
1471
|
-
...reference === null ? {} : { reference }
|
|
1472
|
-
}]);
|
|
1473
|
-
}
|
|
1474
|
-
return createNullPrototypeRecord(normalized);
|
|
1475
|
-
};
|
|
1476
|
-
var findMappingProperty = (node, property) => {
|
|
1477
|
-
if (node.kind !== "mapping") return null;
|
|
1478
|
-
for (const entry of node.entries) if (entry.key.kind === "scalar" && entry.key.value === property) return entry.value;
|
|
1479
|
-
return null;
|
|
1480
|
-
};
|
|
1481
|
-
/**
|
|
1482
|
-
* Detects a supported repository-format version without treating the remaining manifest as valid.
|
|
1483
|
-
* @param node The trustworthy strict-YAML manifest root.
|
|
1484
|
-
* @returns The supported parsed version when its declaration is independently unambiguous.
|
|
1485
|
-
*/
|
|
1486
|
-
var detectSupportedManifestVersion = (node) => {
|
|
1487
|
-
if (node.kind !== "mapping") return null;
|
|
1488
|
-
const versionNode = findMappingProperty(node, "version");
|
|
1489
|
-
return versionNode?.kind === "scalar" && versionNode.value === 1n ? 1 : null;
|
|
1490
|
-
};
|
|
1491
|
-
var validateAgentOwnedIdUniqueness = (node, pointer, context, agentId) => {
|
|
1492
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1493
|
-
for (const property of [
|
|
1494
|
-
"tools",
|
|
1495
|
-
"skills",
|
|
1496
|
-
"unresolved"
|
|
1497
|
-
]) {
|
|
1498
|
-
const record = findMappingProperty(node, property);
|
|
1499
|
-
if (record?.kind !== "mapping") continue;
|
|
1500
|
-
for (const entry of record.entries) {
|
|
1501
|
-
if (entry.key.kind !== "scalar" || typeof entry.key.value !== "string") continue;
|
|
1502
|
-
if (seen.has(entry.key.value)) context.diagnostics.add({
|
|
1503
|
-
code: "MOLDEA_ID_DUPLICATE",
|
|
1504
|
-
entity: { agentId },
|
|
1505
|
-
path: context.path,
|
|
1506
|
-
pointer: childPointer$2(childPointer$2(pointer, property), entry.key.value),
|
|
1507
|
-
range: entry.key.range
|
|
1508
|
-
});
|
|
1509
|
-
seen.add(entry.key.value);
|
|
1510
|
-
}
|
|
1511
|
-
}
|
|
1512
|
-
};
|
|
1513
|
-
var readAgent = (node, pointer, context, agentId) => {
|
|
1514
|
-
const entity = { agentId };
|
|
1515
|
-
const entries = readMapping(node, pointer, /* @__PURE__ */ new Set([
|
|
1516
|
-
"affectedBy",
|
|
1517
|
-
"bindings",
|
|
1518
|
-
"context",
|
|
1519
|
-
"decisions",
|
|
1520
|
-
"runtime",
|
|
1521
|
-
"mirrors",
|
|
1522
|
-
"skills",
|
|
1523
|
-
"tools",
|
|
1524
|
-
"unresolved",
|
|
1525
|
-
"variables"
|
|
1526
|
-
]), context, entity);
|
|
1527
|
-
if (entries === null) return null;
|
|
1528
|
-
validateAgentOwnedIdUniqueness(node, pointer, context, agentId);
|
|
1529
|
-
const runtimeEntry = entries.get("runtime");
|
|
1530
|
-
let runtime = null;
|
|
1531
|
-
if (runtimeEntry === void 0) addInvalidValue(context, childPointer$2(pointer, "runtime"), null, "required", entity);
|
|
1532
|
-
else runtime = readRuntime(runtimeEntry.value, childPointer$2(pointer, "runtime"), context, agentId);
|
|
1533
|
-
const variablesEntry = entries.get("variables");
|
|
1534
|
-
const variables = variablesEntry === void 0 ? null : readVariables(variablesEntry.value, childPointer$2(pointer, "variables"), context, agentId);
|
|
1535
|
-
const declaredVariables = new Set(Object.keys(variables ?? {}));
|
|
1536
|
-
const bindingsEntry = entries.get("bindings");
|
|
1537
|
-
const bindings = bindingsEntry === void 0 ? null : readBindings(bindingsEntry.value, childPointer$2(pointer, "bindings"), context, agentId, declaredVariables);
|
|
1538
|
-
const contextEntry = entries.get("context");
|
|
1539
|
-
const contextPaths = contextEntry === void 0 ? null : readPathList(contextEntry.value, childPointer$2(pointer, "context"), "context", context, entity);
|
|
1540
|
-
const decisionsEntry = entries.get("decisions");
|
|
1541
|
-
const decisions = decisionsEntry === void 0 ? null : readPathList(decisionsEntry.value, childPointer$2(pointer, "decisions"), "decision", context, entity);
|
|
1542
|
-
const toolsEntry = entries.get("tools");
|
|
1543
|
-
const tools = toolsEntry === void 0 ? null : readCapabilities(toolsEntry.value, childPointer$2(pointer, "tools"), context, agentId, "tool");
|
|
1544
|
-
const skillsEntry = entries.get("skills");
|
|
1545
|
-
const skills = skillsEntry === void 0 ? null : readCapabilities(skillsEntry.value, childPointer$2(pointer, "skills"), context, agentId, "skill");
|
|
1546
|
-
const affectedByEntry = entries.get("affectedBy");
|
|
1547
|
-
const affectedBy = affectedByEntry === void 0 ? null : readAffectedBy(affectedByEntry.value, childPointer$2(pointer, "affectedBy"), context, entity);
|
|
1548
|
-
const mirrorsEntry = entries.get("mirrors");
|
|
1549
|
-
const mirrors = mirrorsEntry === void 0 ? null : readPathList(mirrorsEntry.value, childPointer$2(pointer, "mirrors"), "mirror", context, entity);
|
|
1550
|
-
const unresolvedEntry = entries.get("unresolved");
|
|
1551
|
-
const unresolved = unresolvedEntry === void 0 ? null : readUnresolved(unresolvedEntry.value, childPointer$2(pointer, "unresolved"), context, agentId);
|
|
1552
|
-
if (runtime === null) return null;
|
|
1553
|
-
return {
|
|
1554
|
-
runtime,
|
|
1555
|
-
...contextPaths === null ? {} : { context: contextPaths },
|
|
1556
|
-
...decisions === null ? {} : { decisions },
|
|
1557
|
-
...variables === null ? {} : { variables },
|
|
1558
|
-
...bindings === null ? {} : { bindings },
|
|
1559
|
-
...tools === null ? {} : { tools },
|
|
1560
|
-
...skills === null ? {} : { skills },
|
|
1561
|
-
...affectedBy === null ? {} : { affectedBy },
|
|
1562
|
-
...mirrors === null ? {} : { mirrors },
|
|
1563
|
-
...unresolved === null ? {} : { unresolved }
|
|
1564
|
-
};
|
|
1565
|
-
};
|
|
1566
|
-
var readAgents = (node, pointer, context) => {
|
|
1567
|
-
const entries = readMapping(node, pointer, null, context);
|
|
1568
|
-
if (entries === null) return null;
|
|
1569
|
-
const normalized = [];
|
|
1570
|
-
for (const [agentId, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
1571
|
-
const agentPointer = childPointer$2(pointer, agentId);
|
|
1572
|
-
validateStableId(agentId, entry.key.range, agentPointer, context, { agentId });
|
|
1573
|
-
const agent = readAgent(entry.value, agentPointer, context, agentId);
|
|
1574
|
-
if (agent !== null) normalized.push([agentId, agent]);
|
|
1575
|
-
}
|
|
1576
|
-
return createNullPrototypeRecord(normalized);
|
|
1577
|
-
};
|
|
1578
|
-
/**
|
|
1579
|
-
* Validates and normalizes a strict YAML document as a version 1 moldea manifest.
|
|
1580
|
-
* @param node The parser-neutral YAML root node.
|
|
1581
|
-
* @param path The canonical or caller-supplied logical manifest path.
|
|
1582
|
-
* @param diagnostics The operation diagnostic collector.
|
|
1583
|
-
* @param runtimeLocations Mutable private source locations populated for repository inspection.
|
|
1584
|
-
* @returns The normalized manifest when its supported version can be interpreted.
|
|
1585
|
-
*/
|
|
1586
|
-
var validateManifest = (node, path, diagnostics, runtimeLocations) => {
|
|
1587
|
-
const context = {
|
|
1588
|
-
diagnostics,
|
|
1589
|
-
mirrorPaths: /* @__PURE__ */ new Set(),
|
|
1590
|
-
path,
|
|
1591
|
-
runtimeLocations
|
|
1592
|
-
};
|
|
1593
|
-
if (node.kind !== "mapping") {
|
|
1594
|
-
diagnostics.add({
|
|
1595
|
-
code: "MOLDEA_MANIFEST_ROOT_INVALID",
|
|
1596
|
-
path,
|
|
1597
|
-
range: node.range
|
|
1598
|
-
});
|
|
1599
|
-
return null;
|
|
1600
|
-
}
|
|
1601
|
-
const versionNode = findMappingProperty(node, "version");
|
|
1602
|
-
if (versionNode === null) {
|
|
1603
|
-
diagnostics.add({
|
|
1604
|
-
code: "MOLDEA_MANIFEST_VERSION_MISSING",
|
|
1605
|
-
path,
|
|
1606
|
-
pointer: "/version"
|
|
1607
|
-
});
|
|
1608
|
-
return null;
|
|
1609
|
-
}
|
|
1610
|
-
if (!(versionNode.kind === "scalar" && typeof versionNode.value === "bigint") || versionNode.kind !== "scalar" || versionNode.value <= 0n) {
|
|
1611
|
-
diagnostics.add({
|
|
1612
|
-
code: "MOLDEA_MANIFEST_VERSION_INVALID",
|
|
1613
|
-
path,
|
|
1614
|
-
pointer: "/version",
|
|
1615
|
-
range: versionNode.range
|
|
1616
|
-
});
|
|
1617
|
-
return null;
|
|
1618
|
-
}
|
|
1619
|
-
if (versionNode.value !== 1n) {
|
|
1620
|
-
diagnostics.add({
|
|
1621
|
-
code: "MOLDEA_MANIFEST_VERSION_UNSUPPORTED",
|
|
1622
|
-
path,
|
|
1623
|
-
pointer: "/version",
|
|
1624
|
-
range: versionNode.range
|
|
1625
|
-
});
|
|
1626
|
-
return null;
|
|
1627
|
-
}
|
|
1628
|
-
const entries = readMapping(node, "", /* @__PURE__ */ new Set([
|
|
1629
|
-
"agents",
|
|
1630
|
-
"context",
|
|
1631
|
-
"decisions",
|
|
1632
|
-
"unresolved",
|
|
1633
|
-
"version"
|
|
1634
|
-
]), context);
|
|
1635
|
-
if (entries === null) return null;
|
|
1636
|
-
const contextEntry = entries.get("context");
|
|
1637
|
-
const contextRelationships = contextEntry === void 0 ? null : readRelationshipRecord(contextEntry.value, "/context", "context", context);
|
|
1638
|
-
const decisionsEntry = entries.get("decisions");
|
|
1639
|
-
const decisionRelationships = decisionsEntry === void 0 ? null : readRelationshipRecord(decisionsEntry.value, "/decisions", "decision", context);
|
|
1640
|
-
const unresolvedEntry = entries.get("unresolved");
|
|
1641
|
-
const unresolved = unresolvedEntry === void 0 ? null : readUnresolved(unresolvedEntry.value, "/unresolved", context);
|
|
1642
|
-
const agentsEntry = entries.get("agents");
|
|
1643
|
-
const agents = agentsEntry === void 0 ? null : readAgents(agentsEntry.value, "/agents", context);
|
|
1644
|
-
return {
|
|
1645
|
-
version: 1,
|
|
1646
|
-
...contextRelationships === null ? {} : { context: contextRelationships },
|
|
1647
|
-
...decisionRelationships === null ? {} : { decisions: decisionRelationships },
|
|
1648
|
-
...unresolved === null ? {} : { unresolved },
|
|
1649
|
-
...agents === null ? {} : { agents }
|
|
1650
|
-
};
|
|
1651
|
-
};
|
|
1652
|
-
//#endregion
|
|
1653
|
-
//#region src/manifest/index.ts
|
|
1654
|
-
/**
|
|
1655
|
-
* Inspects one complete manifest while retaining an independently trustworthy supported version.
|
|
1656
|
-
* @param input The canonical logical path and exact manifest text or bytes.
|
|
1657
|
-
* @param options The immutable Core limits and adapter snapshots.
|
|
1658
|
-
* @param operation The owning public or repository-level operation for typed failures.
|
|
1659
|
-
* @returns Frozen inspection state with all-or-nothing manifest assets and values.
|
|
1660
|
-
* @throws
|
|
1661
|
-
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
1662
|
-
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
1663
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1664
|
-
*/
|
|
1665
|
-
var inspectManifestDocument = async (input, options, operation = "parse-manifest") => {
|
|
1666
|
-
options = createCoreOperationOptionsSnapshot(options);
|
|
1667
|
-
const normalized = normalizeTextDocument(input, options.limits, operation, "maxManifestBytes");
|
|
1668
|
-
const path = parseRepositoryPath(input.path);
|
|
1669
|
-
const diagnostics = createCoreDiagnosticCollector(options.limits, operation);
|
|
1670
|
-
if (!isCanonicalManifestPath(path)) diagnostics.add({
|
|
1671
|
-
code: "MOLDEA_MANIFEST_PATH_INVALID",
|
|
1672
|
-
path
|
|
1673
|
-
});
|
|
1674
|
-
for (const diagnostic of normalized.diagnostics) diagnostics.merge(diagnostic);
|
|
1675
|
-
if (!normalized.valid || normalized.text === null) return freezeRecursively({
|
|
1676
|
-
asset: null,
|
|
1677
|
-
diagnostics: diagnostics.finalize(),
|
|
1678
|
-
formatVersion: null,
|
|
1679
|
-
manifest: null,
|
|
1680
|
-
runtimeLocations: [],
|
|
1681
|
-
valid: false
|
|
1682
|
-
});
|
|
1683
|
-
const locator = createSourceLocator(normalized.text.value);
|
|
1684
|
-
const parsed = parseStrictYaml(normalized.text.value, path, locator, diagnostics);
|
|
1685
|
-
const formatVersion = parsed.value === null ? null : detectSupportedManifestVersion(parsed.value);
|
|
1686
|
-
const runtimeLocations = [];
|
|
1687
|
-
const manifest = parsed.valid && parsed.value !== null ? validateManifest(parsed.value, path, diagnostics, runtimeLocations) : null;
|
|
1688
|
-
if (manifest === null || diagnostics.size > 0) return freezeRecursively({
|
|
1689
|
-
asset: null,
|
|
1690
|
-
diagnostics: diagnostics.finalize(),
|
|
1691
|
-
formatVersion,
|
|
1692
|
-
manifest: null,
|
|
1693
|
-
runtimeLocations,
|
|
1694
|
-
valid: false
|
|
1695
|
-
});
|
|
1696
|
-
const digest = await calculateNormalizedTextDigest(normalized.text);
|
|
1697
|
-
const asset = {
|
|
1698
|
-
content: normalized.text.value,
|
|
1699
|
-
digest,
|
|
1700
|
-
path,
|
|
1701
|
-
scalarLength: normalized.text.scalarLength,
|
|
1702
|
-
utf8ByteLength: normalized.text.utf8ByteLength
|
|
1703
|
-
};
|
|
1704
|
-
return freezeRecursively({
|
|
1705
|
-
asset,
|
|
1706
|
-
diagnostics: diagnostics.finalize(),
|
|
1707
|
-
formatVersion,
|
|
1708
|
-
manifest,
|
|
1709
|
-
runtimeLocations,
|
|
1710
|
-
valid: true
|
|
1711
|
-
});
|
|
1712
|
-
};
|
|
1713
|
-
/**
|
|
1714
|
-
* Parses and validates one complete version 1 manifest document.
|
|
1715
|
-
* @param input The canonical logical path and exact manifest text or bytes.
|
|
1716
|
-
* @param options The immutable Core limits and adapter snapshots.
|
|
1717
|
-
* @returns A frozen all-or-nothing manifest parse result.
|
|
1718
|
-
* @throws
|
|
1719
|
-
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
1720
|
-
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
1721
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1722
|
-
*/
|
|
1723
|
-
var parseManifestDocument = async (input, options, operation = "parse-manifest") => {
|
|
1724
|
-
const inspection = await inspectManifestDocument(input, options, operation);
|
|
1725
|
-
return freezeRecursively({
|
|
1726
|
-
asset: inspection.asset,
|
|
1727
|
-
diagnostics: inspection.diagnostics,
|
|
1728
|
-
manifest: inspection.manifest,
|
|
1729
|
-
valid: inspection.valid
|
|
1730
|
-
});
|
|
1731
|
-
};
|
|
1732
|
-
//#endregion
|
|
1733
|
-
//#region src/project-agent-assignments/index.ts
|
|
1734
|
-
/** Iterates content-free agent-to-runtime assignments without retaining an intermediate array. */
|
|
1735
|
-
var iterateProjectAgentAssignments = function* (project) {
|
|
1736
|
-
for (const agent of project.agents) yield {
|
|
1737
|
-
agentId: agent.id,
|
|
1738
|
-
runtimeId: agent.declaration.runtime.id
|
|
1739
|
-
};
|
|
410
|
+
//#region src/project-agent-assignments/index.ts
|
|
411
|
+
/** Iterates content-free agent-to-runtime assignments without retaining an intermediate array. */
|
|
412
|
+
var iterateProjectAgentAssignments = function* (project) {
|
|
413
|
+
for (const agent of project.agents) yield {
|
|
414
|
+
agentId: agent.id,
|
|
415
|
+
runtimeId: agent.declaration.runtime.id
|
|
416
|
+
};
|
|
1740
417
|
};
|
|
1741
418
|
//#endregion
|
|
1742
419
|
//#region src/project-metadata/index.ts
|
|
@@ -1766,674 +443,54 @@ var iterateProjectMetadata = function* (project) {
|
|
|
1766
443
|
byteLength: mirror.byteLength,
|
|
1767
444
|
canonicalDigest: mirror.canonicalDigest,
|
|
1768
445
|
decisionId: null,
|
|
1769
|
-
digest: mirror.digest,
|
|
1770
|
-
kind: "mirror",
|
|
1771
|
-
path: mirror.path,
|
|
1772
|
-
scalarLength: mirror.scalarLength
|
|
1773
|
-
};
|
|
1774
|
-
}
|
|
1775
|
-
};
|
|
1776
|
-
/** Creates the content-free summary for one validated project snapshot. */
|
|
1777
|
-
var createProjectSummary = (project) => ({
|
|
1778
|
-
counts: {
|
|
1779
|
-
agents: project.agents.length,
|
|
1780
|
-
context: project.context.length,
|
|
1781
|
-
decisions: project.decisions.length,
|
|
1782
|
-
mirrors: project.agents.reduce((count, agent) => count + agent.mirrors.length, 0),
|
|
1783
|
-
runtimes: project.runtimes.length,
|
|
1784
|
-
unresolved: project.agents.reduce((count, agent) => count + Object.keys(agent.declaration.unresolved ?? {}).length, Object.keys(project.unresolved).length)
|
|
1785
|
-
},
|
|
1786
|
-
manifestDigest: project.manifest.asset.digest,
|
|
1787
|
-
manifestPath: project.manifest.asset.path,
|
|
1788
|
-
projectDigest: project.project.digest,
|
|
1789
|
-
projectPath: project.project.path
|
|
1790
|
-
});
|
|
1791
|
-
//#endregion
|
|
1792
|
-
//#region src/adapter-availability/index.ts
|
|
1793
|
-
/**
|
|
1794
|
-
* Validates adapter availability and format support before any runtime adapter runs.
|
|
1795
|
-
* @param locations The recognized runtime declarations retained from manifest parsing.
|
|
1796
|
-
* @param formatVersion The active repository-format version.
|
|
1797
|
-
* @param options The immutable Core adapter registry and limits.
|
|
1798
|
-
* @returns Frozen deterministic preflight diagnostics.
|
|
1799
|
-
* @throws
|
|
1800
|
-
* - RESOURCE_LIMIT_EXCEEDED: The raw Core diagnostic limit was exceeded.
|
|
1801
|
-
*/
|
|
1802
|
-
var validateRuntimeAdapterAvailability = (locations, formatVersion, options) => {
|
|
1803
|
-
const diagnostics = createCoreDiagnosticCollector(options.limits, "validate-project");
|
|
1804
|
-
const adapters = new Map(options.adapters.map((adapter) => [adapter.id, adapter]));
|
|
1805
|
-
for (const location of locations) {
|
|
1806
|
-
if (location.adapterId === "custom") continue;
|
|
1807
|
-
const adapter = adapters.get(location.adapterId);
|
|
1808
|
-
if (adapter === void 0) {
|
|
1809
|
-
diagnostics.add({
|
|
1810
|
-
code: "MOLDEA_RUNTIME_ADAPTER_UNAVAILABLE",
|
|
1811
|
-
entity: {
|
|
1812
|
-
adapterId: location.adapterId,
|
|
1813
|
-
agentId: location.agentId
|
|
1814
|
-
},
|
|
1815
|
-
path: location.path,
|
|
1816
|
-
pointer: location.pointer,
|
|
1817
|
-
range: location.range
|
|
1818
|
-
});
|
|
1819
|
-
continue;
|
|
1820
|
-
}
|
|
1821
|
-
if (!adapter.supportedRepositoryFormatVersions.includes(formatVersion)) diagnostics.add({
|
|
1822
|
-
code: "MOLDEA_RUNTIME_ADAPTER_FORMAT_UNSUPPORTED",
|
|
1823
|
-
entity: {
|
|
1824
|
-
adapterId: location.adapterId,
|
|
1825
|
-
agentId: location.agentId
|
|
1826
|
-
},
|
|
1827
|
-
path: location.path,
|
|
1828
|
-
pointer: location.pointer,
|
|
1829
|
-
range: location.range
|
|
1830
|
-
});
|
|
1831
|
-
}
|
|
1832
|
-
return diagnostics.finalize();
|
|
1833
|
-
};
|
|
1834
|
-
//#endregion
|
|
1835
|
-
//#region src/adapter-validation/index.ts
|
|
1836
|
-
var EVIDENCE_KINDS = /* @__PURE__ */ new Set([
|
|
1837
|
-
"runtime-package",
|
|
1838
|
-
"language",
|
|
1839
|
-
"agent-definition",
|
|
1840
|
-
"instruction-loader",
|
|
1841
|
-
"schema",
|
|
1842
|
-
"tool-registration",
|
|
1843
|
-
"skill-registration",
|
|
1844
|
-
"handoff-registration",
|
|
1845
|
-
"variable-provider",
|
|
1846
|
-
"runtime-pattern"
|
|
1847
|
-
]);
|
|
1848
|
-
var DIAGNOSTIC_ENTITY_KEYS = /* @__PURE__ */ new Set([
|
|
1849
|
-
"agentId",
|
|
1850
|
-
"capabilityKind",
|
|
1851
|
-
"capabilityId",
|
|
1852
|
-
"decisionId",
|
|
1853
|
-
"variableId",
|
|
1854
|
-
"adapterId"
|
|
1855
|
-
]);
|
|
1856
|
-
var POSITION_KEYS = /* @__PURE__ */ new Set([
|
|
1857
|
-
"line",
|
|
1858
|
-
"column",
|
|
1859
|
-
"offset"
|
|
1860
|
-
]);
|
|
1861
|
-
var RANGE_KEYS = /* @__PURE__ */ new Set(["start", "end"]);
|
|
1862
|
-
var REFERENCE_KEYS = /* @__PURE__ */ new Set(["path", "symbol"]);
|
|
1863
|
-
var EVIDENCE_KEYS = /* @__PURE__ */ new Set([
|
|
1864
|
-
"source",
|
|
1865
|
-
"kind",
|
|
1866
|
-
"agentId",
|
|
1867
|
-
"capabilityKind",
|
|
1868
|
-
"capabilityId",
|
|
1869
|
-
"runtimeName",
|
|
1870
|
-
"references",
|
|
1871
|
-
"details"
|
|
1872
|
-
]);
|
|
1873
|
-
var DIAGNOSTIC_KEYS = /* @__PURE__ */ new Set([
|
|
1874
|
-
"source",
|
|
1875
|
-
"severity",
|
|
1876
|
-
"code",
|
|
1877
|
-
"message",
|
|
1878
|
-
"path",
|
|
1879
|
-
"pointer",
|
|
1880
|
-
"range",
|
|
1881
|
-
"entity",
|
|
1882
|
-
"details"
|
|
1883
|
-
]);
|
|
1884
|
-
var ADAPTER_RESULT_KEYS = /* @__PURE__ */ new Set(["evidence", "diagnostics"]);
|
|
1885
|
-
var ADAPTER_CODE_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
|
|
1886
|
-
var UNVERIFIED_MESSAGE = "The declared runtime relationship could not be verified.";
|
|
1887
|
-
var UNVERIFIED_RELATIONSHIPS = /* @__PURE__ */ new Set([
|
|
1888
|
-
"runtime-agent",
|
|
1889
|
-
"instruction-loader",
|
|
1890
|
-
"agent-input-schema",
|
|
1891
|
-
"agent-output-schema",
|
|
1892
|
-
"tool-implementation",
|
|
1893
|
-
"tool-registration",
|
|
1894
|
-
"tool-input-schema",
|
|
1895
|
-
"tool-output-schema",
|
|
1896
|
-
"skill-implementation",
|
|
1897
|
-
"skill-registration",
|
|
1898
|
-
"handoff-registration",
|
|
1899
|
-
"routing-description",
|
|
1900
|
-
"variable-provider"
|
|
1901
|
-
]);
|
|
1902
|
-
var SIMPLE_WARNING_KEYS = /* @__PURE__ */ new Set(["relationship", "reason"]);
|
|
1903
|
-
var VERSION_WARNING_KEYS = /* @__PURE__ */ new Set([
|
|
1904
|
-
"relationship",
|
|
1905
|
-
"reason",
|
|
1906
|
-
"packageName",
|
|
1907
|
-
"declaredRange",
|
|
1908
|
-
"boundaryVersion"
|
|
1909
|
-
]);
|
|
1910
|
-
var PACKAGE_NAME_PATTERN = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/u;
|
|
1911
|
-
var BOUNDARY_VERSION_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/u;
|
|
1912
|
-
var RANGE_COMPARATOR_PATTERN = new RegExp(`^(?:<=|>=|<|>|=)?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$`, "u");
|
|
1913
|
-
var isRecord$2 = (candidate) => {
|
|
1914
|
-
return typeof candidate === "object" && candidate !== null && !Array.isArray(candidate);
|
|
1915
|
-
};
|
|
1916
|
-
var invalidAdapterResult = (adapterId) => {
|
|
1917
|
-
throw new CoreOperationException({
|
|
1918
|
-
adapterId,
|
|
1919
|
-
cause: /* @__PURE__ */ new TypeError("The runtime adapter result is invalid."),
|
|
1920
|
-
code: "ADAPTER_EXECUTION_FAILED",
|
|
1921
|
-
operation: "validate-adapter"
|
|
1922
|
-
});
|
|
1923
|
-
};
|
|
1924
|
-
var registerRawOutput = (outputCounts, key, amount, context) => {
|
|
1925
|
-
const limit = key === "diagnostics" ? "maxDiagnostics" : "maxEvidence";
|
|
1926
|
-
if (key === "diagnostics") {
|
|
1927
|
-
outputCounts.diagnostics = registerCoreDiagnosticCandidates(context.limits, amount, "validate-adapter", outputCounts.diagnostics, context.adapterId);
|
|
1928
|
-
return;
|
|
1929
|
-
}
|
|
1930
|
-
if (amount > context.limits[limit] - outputCounts[key]) throw new CoreOperationException({
|
|
1931
|
-
adapterId: context.adapterId,
|
|
1932
|
-
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
1933
|
-
limit,
|
|
1934
|
-
limitMaximum: context.limits[limit],
|
|
1935
|
-
nextAction: "reduce-input-or-increase-limit",
|
|
1936
|
-
observedUsage: outputCounts[key] + amount,
|
|
1937
|
-
operation: "validate-adapter"
|
|
1938
|
-
});
|
|
1939
|
-
outputCounts[key] += amount;
|
|
1940
|
-
};
|
|
1941
|
-
var hasOnlyKeys = (candidate, keys) => {
|
|
1942
|
-
return Reflect.ownKeys(candidate).every((key) => {
|
|
1943
|
-
if (typeof key !== "string" || !keys.has(key)) return false;
|
|
1944
|
-
const descriptor = Object.getOwnPropertyDescriptor(candidate, key);
|
|
1945
|
-
return descriptor !== void 0 && descriptor.enumerable && "value" in descriptor;
|
|
1946
|
-
});
|
|
1947
|
-
};
|
|
1948
|
-
var isSafeString = (candidate) => {
|
|
1949
|
-
return typeof candidate === "string" && isUnicodeScalarText(candidate) && !candidate.includes("\0");
|
|
1950
|
-
};
|
|
1951
|
-
var normalizeDetails = (candidate, adapterId) => {
|
|
1952
|
-
if (!isRecord$2(candidate)) return invalidAdapterResult(adapterId);
|
|
1953
|
-
const entries = [];
|
|
1954
|
-
for (const key of Reflect.ownKeys(candidate)) {
|
|
1955
|
-
if (typeof key !== "string" || !isUnicodeScalarText(key) || key.includes("\0")) return invalidAdapterResult(adapterId);
|
|
1956
|
-
const descriptor = Object.getOwnPropertyDescriptor(candidate, key);
|
|
1957
|
-
if (descriptor === void 0 || !descriptor.enumerable || !("value" in descriptor)) return invalidAdapterResult(adapterId);
|
|
1958
|
-
const detail = descriptor.value;
|
|
1959
|
-
if (detail !== null && typeof detail !== "boolean" && !(typeof detail === "string" && isUnicodeScalarText(detail) && !detail.includes("\0")) && !(typeof detail === "number" && Number.isFinite(detail))) return invalidAdapterResult(adapterId);
|
|
1960
|
-
entries.push([key, typeof detail === "number" && Object.is(detail, -0) ? 0 : detail]);
|
|
1961
|
-
}
|
|
1962
|
-
return normalizeDiagnosticDetails(createNullPrototypeRecord(entries));
|
|
1963
|
-
};
|
|
1964
|
-
var normalizePosition = (candidate, adapterId) => {
|
|
1965
|
-
if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, POSITION_KEYS) || !Number.isSafeInteger(candidate["line"]) || !Number.isSafeInteger(candidate["column"]) || !Number.isSafeInteger(candidate["offset"]) || candidate["line"] < 1 || candidate["column"] < 1 || candidate["offset"] < 0) return invalidAdapterResult(adapterId);
|
|
1966
|
-
return freezeRecursively({
|
|
1967
|
-
column: candidate["column"],
|
|
1968
|
-
line: candidate["line"],
|
|
1969
|
-
offset: candidate["offset"]
|
|
1970
|
-
});
|
|
1971
|
-
};
|
|
1972
|
-
var normalizeRange = (candidate, adapterId) => {
|
|
1973
|
-
if (candidate === null) return null;
|
|
1974
|
-
if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, RANGE_KEYS)) return invalidAdapterResult(adapterId);
|
|
1975
|
-
const start = normalizePosition(candidate["start"], adapterId);
|
|
1976
|
-
const end = normalizePosition(candidate["end"], adapterId);
|
|
1977
|
-
if (!(end.line > start.line || end.line === start.line && end.column >= start.column) || end.offset < start.offset) return invalidAdapterResult(adapterId);
|
|
1978
|
-
return freezeRecursively({
|
|
1979
|
-
end,
|
|
1980
|
-
start
|
|
1981
|
-
});
|
|
1982
|
-
};
|
|
1983
|
-
var isJsonPointer = (candidate) => {
|
|
1984
|
-
return isUnicodeScalarText(candidate) && !candidate.includes("\0") && (candidate === "" || candidate.startsWith("/") && !/~(?![01])/u.test(candidate));
|
|
1985
|
-
};
|
|
1986
|
-
var readCapability = (agent, capabilityKind, capabilityId) => {
|
|
1987
|
-
const capabilities = capabilityKind === "tool" ? agent.declaration.tools : agent.declaration.skills;
|
|
1988
|
-
return capabilities !== void 0 && Object.hasOwn(capabilities, capabilityId) ? capabilities[capabilityId] : void 0;
|
|
1989
|
-
};
|
|
1990
|
-
var normalizeEntity = (candidate, context) => {
|
|
1991
|
-
if (candidate === null) return null;
|
|
1992
|
-
if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, DIAGNOSTIC_ENTITY_KEYS)) return invalidAdapterResult(context.adapterId);
|
|
1993
|
-
const entity = {};
|
|
1994
|
-
for (const key of DIAGNOSTIC_ENTITY_KEYS) {
|
|
1995
|
-
const candidateValue = candidate[key];
|
|
1996
|
-
if (candidateValue === void 0) continue;
|
|
1997
|
-
if (!isSafeString(candidateValue) || candidateValue.length === 0) return invalidAdapterResult(context.adapterId);
|
|
1998
|
-
entity[key] = candidateValue;
|
|
1999
|
-
}
|
|
2000
|
-
const agentId = entity["agentId"];
|
|
2001
|
-
const agent = agentId === void 0 ? void 0 : context.agentsById.get(agentId);
|
|
2002
|
-
if (agentId !== void 0 && agent === void 0) return invalidAdapterResult(context.adapterId);
|
|
2003
|
-
if (entity["adapterId"] !== void 0 && entity["adapterId"] !== context.adapterId) return invalidAdapterResult(context.adapterId);
|
|
2004
|
-
const capabilityKind = entity["capabilityKind"];
|
|
2005
|
-
const capabilityId = entity["capabilityId"];
|
|
2006
|
-
if (capabilityKind === void 0 !== (capabilityId === void 0) || capabilityKind !== void 0 && capabilityKind !== "tool" && capabilityKind !== "skill" || capabilityKind !== void 0 && capabilityId !== void 0 && (agent === void 0 || readCapability(agent, capabilityKind, capabilityId) === void 0)) return invalidAdapterResult(context.adapterId);
|
|
2007
|
-
const variableId = entity["variableId"];
|
|
2008
|
-
if (variableId !== void 0 && (agent === void 0 || agent.declaration.variables === void 0 || !Object.hasOwn(agent.declaration.variables, variableId))) return invalidAdapterResult(context.adapterId);
|
|
2009
|
-
const decisionId = entity["decisionId"];
|
|
2010
|
-
if (decisionId !== void 0 && !context.decisionIds.has(decisionId)) return invalidAdapterResult(context.adapterId);
|
|
2011
|
-
return normalizeDiagnosticEntity(entity);
|
|
2012
|
-
};
|
|
2013
|
-
/** Checks only the safe wire grammar; adapters own SemVer meaning and normalization. */
|
|
2014
|
-
var isNormalizedRangeWire = (candidate) => {
|
|
2015
|
-
if (candidate === "*") return true;
|
|
2016
|
-
return candidate.split(" || ").every((set) => {
|
|
2017
|
-
const comparators = set.split(" ");
|
|
2018
|
-
return comparators.length > 0 && comparators.every((part) => RANGE_COMPARATOR_PATTERN.test(part));
|
|
2019
|
-
});
|
|
2020
|
-
};
|
|
2021
|
-
var isValidWarningSubject = (relationship, entity, context) => {
|
|
2022
|
-
if (entity?.agentId === void 0 || entity.decisionId !== void 0) return false;
|
|
2023
|
-
const agent = context.agentsById.get(entity.agentId);
|
|
2024
|
-
if (agent === void 0) return false;
|
|
2025
|
-
if (relationship === "variable-provider") return entity.capabilityKind === void 0 && entity.capabilityId === void 0 && entity.variableId !== void 0 && agent.declaration.bindings?.variableProviders?.[entity.variableId] !== void 0;
|
|
2026
|
-
if (entity.variableId !== void 0) return false;
|
|
2027
|
-
if (relationship.startsWith("tool-")) {
|
|
2028
|
-
if (entity.capabilityKind !== "tool" || entity.capabilityId === void 0) return false;
|
|
2029
|
-
const tool = agent.declaration.tools?.[entity.capabilityId];
|
|
2030
|
-
return tool !== void 0 && (relationship !== "tool-input-schema" || tool.inputSchema !== void 0) && (relationship !== "tool-output-schema" || tool.outputSchema !== void 0);
|
|
2031
|
-
}
|
|
2032
|
-
if (relationship.startsWith("skill-")) return entity.capabilityKind === "skill" && entity.capabilityId !== void 0 && agent.declaration.skills?.[entity.capabilityId] !== void 0;
|
|
2033
|
-
if (entity.capabilityKind !== void 0 || entity.capabilityId !== void 0) return false;
|
|
2034
|
-
if (relationship === "runtime-agent") return agent.declaration.bindings?.runtimeAgent !== void 0;
|
|
2035
|
-
if (relationship === "instruction-loader") return agent.declaration.bindings?.instructionLoader !== void 0;
|
|
2036
|
-
if (relationship === "agent-input-schema") return agent.declaration.bindings?.inputSchema !== void 0;
|
|
2037
|
-
if (relationship === "agent-output-schema") return agent.declaration.bindings?.outputSchema !== void 0;
|
|
2038
|
-
return relationship === "handoff-registration" || relationship === "routing-description";
|
|
2039
|
-
};
|
|
2040
|
-
var normalizeWarningDetails = (candidate, entity, context) => {
|
|
2041
|
-
const details = normalizeDetails(candidate, context.adapterId);
|
|
2042
|
-
const relationship = details["relationship"];
|
|
2043
|
-
const reason = details["reason"];
|
|
2044
|
-
if (typeof relationship !== "string" || !UNVERIFIED_RELATIONSHIPS.has(relationship) || !isValidWarningSubject(relationship, entity, context)) return invalidAdapterResult(context.adapterId);
|
|
2045
|
-
if (reason === "unsupported-source-pattern" || reason === "dynamic-source-pattern") {
|
|
2046
|
-
if (!hasOnlyKeys(details, SIMPLE_WARNING_KEYS)) return invalidAdapterResult(context.adapterId);
|
|
2047
|
-
return freezeRecursively({
|
|
2048
|
-
relationship,
|
|
2049
|
-
reason
|
|
2050
|
-
});
|
|
2051
|
-
}
|
|
2052
|
-
if (reason !== "version-dependent-behavior" || !hasOnlyKeys(details, VERSION_WARNING_KEYS)) return invalidAdapterResult(context.adapterId);
|
|
2053
|
-
const packageName = details["packageName"];
|
|
2054
|
-
const declaredRange = details["declaredRange"];
|
|
2055
|
-
const boundaryVersion = details["boundaryVersion"];
|
|
2056
|
-
if (typeof packageName !== "string" || !PACKAGE_NAME_PATTERN.test(packageName) || declaredRange !== null && (typeof declaredRange !== "string" || !isNormalizedRangeWire(declaredRange)) || typeof boundaryVersion !== "string" || !BOUNDARY_VERSION_PATTERN.test(boundaryVersion)) return invalidAdapterResult(context.adapterId);
|
|
2057
|
-
return freezeRecursively({
|
|
2058
|
-
boundaryVersion,
|
|
2059
|
-
declaredRange,
|
|
2060
|
-
packageName,
|
|
2061
|
-
reason,
|
|
2062
|
-
relationship
|
|
2063
|
-
});
|
|
2064
|
-
};
|
|
2065
|
-
var normalizeReference = (candidate, adapterId) => {
|
|
2066
|
-
if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, REFERENCE_KEYS)) return invalidAdapterResult(adapterId);
|
|
2067
|
-
const pathCandidate = candidate["path"];
|
|
2068
|
-
const symbolCandidate = candidate["symbol"];
|
|
2069
|
-
if (typeof pathCandidate !== "string" || !isRepositoryPath(pathCandidate)) return invalidAdapterResult(adapterId);
|
|
2070
|
-
const path = parseRepositoryPath(pathCandidate);
|
|
2071
|
-
if (symbolCandidate !== void 0 && (typeof symbolCandidate !== "string" || !isUnicodeScalarText(symbolCandidate) || !isRepositorySymbol(symbolCandidate) || isCanonicalMoldeaPath(path))) return invalidAdapterResult(adapterId);
|
|
2072
|
-
return freezeRecursively({
|
|
2073
|
-
path,
|
|
2074
|
-
...symbolCandidate === void 0 ? {} : { symbol: symbolCandidate }
|
|
2075
|
-
});
|
|
2076
|
-
};
|
|
2077
|
-
var normalizeReferences = (candidate, adapterId) => {
|
|
2078
|
-
if (!Array.isArray(candidate) || candidate.length === 0) return invalidAdapterResult(adapterId);
|
|
2079
|
-
const references = candidate.map((reference) => normalizeReference(reference, adapterId));
|
|
2080
|
-
const referenceKeys = /* @__PURE__ */ new Set();
|
|
2081
|
-
for (const reference of references) {
|
|
2082
|
-
const key = JSON.stringify([reference.path, reference.symbol ?? null]);
|
|
2083
|
-
if (referenceKeys.has(key)) return invalidAdapterResult(adapterId);
|
|
2084
|
-
referenceKeys.add(key);
|
|
2085
|
-
}
|
|
2086
|
-
return freezeRecursively(sortRepositoryReferences(references));
|
|
2087
|
-
};
|
|
2088
|
-
var normalizeEvidence = (candidate, context) => {
|
|
2089
|
-
if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, EVIDENCE_KEYS)) return invalidAdapterResult(context.adapterId);
|
|
2090
|
-
const source = candidate["source"];
|
|
2091
|
-
const kind = candidate["kind"];
|
|
2092
|
-
const agentId = candidate["agentId"];
|
|
2093
|
-
const capabilityKind = candidate["capabilityKind"];
|
|
2094
|
-
const capabilityId = candidate["capabilityId"];
|
|
2095
|
-
const runtimeName = candidate["runtimeName"];
|
|
2096
|
-
if (source !== context.adapterId || typeof kind !== "string" || !EVIDENCE_KINDS.has(kind) || agentId !== null && !isSafeString(agentId) || capabilityKind !== null && capabilityKind !== "tool" && capabilityKind !== "skill" || capabilityId !== null && !isSafeString(capabilityId) || runtimeName !== null && (!isSafeString(runtimeName) || !isNonEmptySingleLine(runtimeName) || hasSurroundingWhitespace(runtimeName))) return invalidAdapterResult(context.adapterId);
|
|
2097
|
-
const scopedAgent = agentId === null ? void 0 : context.agentsById.get(agentId);
|
|
2098
|
-
if (agentId !== null && scopedAgent === void 0 || capabilityKind === null !== (capabilityId === null) || capabilityKind !== null && capabilityId !== null && (scopedAgent === void 0 || readCapability(scopedAgent, capabilityKind, capabilityId) === void 0)) return invalidAdapterResult(context.adapterId);
|
|
2099
|
-
return freezeRecursively({
|
|
2100
|
-
agentId,
|
|
2101
|
-
capabilityId,
|
|
2102
|
-
capabilityKind,
|
|
2103
|
-
details: normalizeDetails(candidate["details"], context.adapterId),
|
|
2104
|
-
kind,
|
|
2105
|
-
references: normalizeReferences(candidate["references"], context.adapterId),
|
|
2106
|
-
runtimeName,
|
|
2107
|
-
source
|
|
2108
|
-
});
|
|
2109
|
-
};
|
|
2110
|
-
var validateEvidenceReferences = async (evidence, context) => {
|
|
2111
|
-
const entries = /* @__PURE__ */ new Map();
|
|
2112
|
-
const operationOptions = context.signal === void 0 ? void 0 : { signal: context.signal };
|
|
2113
|
-
for (const item of evidence) for (const reference of item.references) {
|
|
2114
|
-
let entry = entries.get(reference.path);
|
|
2115
|
-
if (entry === void 0 && !entries.has(reference.path)) {
|
|
2116
|
-
entry = await context.repository.getEntry(reference.path, operationOptions);
|
|
2117
|
-
entries.set(reference.path, entry);
|
|
2118
|
-
}
|
|
2119
|
-
if (entry?.type !== "file") return invalidAdapterResult(context.adapterId);
|
|
2120
|
-
}
|
|
2121
|
-
};
|
|
2122
|
-
var normalizeDiagnostic = (candidate, context) => {
|
|
2123
|
-
if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, DIAGNOSTIC_KEYS)) return invalidAdapterResult(context.adapterId);
|
|
2124
|
-
const source = candidate["source"];
|
|
2125
|
-
const severity = candidate["severity"];
|
|
2126
|
-
const code = candidate["code"];
|
|
2127
|
-
const message = candidate["message"];
|
|
2128
|
-
const pathCandidate = candidate["path"];
|
|
2129
|
-
const pointer = candidate["pointer"];
|
|
2130
|
-
const namespace = `${context.adapterId.toUpperCase().replaceAll("-", "_")}_`;
|
|
2131
|
-
const isUnverified = code === `${namespace}RUNTIME_RELATIONSHIP_UNVERIFIED`;
|
|
2132
|
-
if (source !== context.adapterId || !isSafeString(code) || !ADAPTER_CODE_PATTERN.test(code) || !code.startsWith(namespace) || code.length === namespace.length || (isUnverified ? severity !== "warning" || message !== UNVERIFIED_MESSAGE : severity !== "error") || !isSafeString(message) || message.length === 0 || pathCandidate !== null && (typeof pathCandidate !== "string" || !isRepositoryPath(pathCandidate)) || pointer !== null && (typeof pointer !== "string" || !isJsonPointer(pointer))) return invalidAdapterResult(context.adapterId);
|
|
2133
|
-
const path = pathCandidate === null ? null : parseRepositoryPath(pathCandidate);
|
|
2134
|
-
const range = normalizeRange(candidate["range"], context.adapterId);
|
|
2135
|
-
const entity = normalizeEntity(candidate["entity"], context);
|
|
2136
|
-
if (path === null && (pointer !== null || range !== null)) return invalidAdapterResult(context.adapterId);
|
|
2137
|
-
if (isUnverified) {
|
|
2138
|
-
if (path === null) return invalidAdapterResult(context.adapterId);
|
|
2139
|
-
return freezeRecursively({
|
|
2140
|
-
code,
|
|
2141
|
-
details: normalizeWarningDetails(candidate["details"], entity, context),
|
|
2142
|
-
entity,
|
|
2143
|
-
message,
|
|
2144
|
-
path,
|
|
2145
|
-
pointer,
|
|
2146
|
-
range,
|
|
2147
|
-
severity: "warning",
|
|
2148
|
-
source
|
|
2149
|
-
});
|
|
2150
|
-
}
|
|
2151
|
-
return freezeRecursively({
|
|
2152
|
-
code,
|
|
2153
|
-
details: normalizeDetails(candidate["details"], context.adapterId),
|
|
2154
|
-
entity,
|
|
2155
|
-
message,
|
|
2156
|
-
path,
|
|
2157
|
-
pointer,
|
|
2158
|
-
range,
|
|
2159
|
-
severity: "error",
|
|
2160
|
-
source
|
|
2161
|
-
});
|
|
2162
|
-
};
|
|
2163
|
-
var compareNullableStrings$1 = (left, right) => {
|
|
2164
|
-
return left === null ? right === null ? 0 : -1 : right === null ? 1 : compareExactStrings(left, right);
|
|
2165
|
-
};
|
|
2166
|
-
var compareEvidence = (left, right) => {
|
|
2167
|
-
const leftReferences = JSON.stringify(left.references.map((reference) => [reference.path, reference.symbol ?? null]));
|
|
2168
|
-
const rightReferences = JSON.stringify(right.references.map((reference) => [reference.path, reference.symbol ?? null]));
|
|
2169
|
-
return compareExactStrings(left.source, right.source) || compareExactStrings(left.kind, right.kind) || compareNullableStrings$1(left.agentId, right.agentId) || compareNullableStrings$1(left.capabilityKind, right.capabilityKind) || compareNullableStrings$1(left.capabilityId, right.capabilityId) || compareNullableStrings$1(left.runtimeName, right.runtimeName) || compareExactStrings(leftReferences, rightReferences) || compareExactStrings(serializeDiagnosticDetails(left.details), serializeDiagnosticDetails(right.details));
|
|
2170
|
-
};
|
|
2171
|
-
var serializeEvidence = (evidence) => {
|
|
2172
|
-
return JSON.stringify([
|
|
2173
|
-
evidence.source,
|
|
2174
|
-
evidence.kind,
|
|
2175
|
-
evidence.agentId,
|
|
2176
|
-
evidence.capabilityKind,
|
|
2177
|
-
evidence.capabilityId,
|
|
2178
|
-
evidence.runtimeName,
|
|
2179
|
-
evidence.references.map((reference) => [reference.path, reference.symbol ?? null]),
|
|
2180
|
-
serializeDiagnosticDetails(evidence.details)
|
|
2181
|
-
]);
|
|
2182
|
-
};
|
|
2183
|
-
/**
|
|
2184
|
-
* Deduplicates and sorts normalized evidence from every completed adapter.
|
|
2185
|
-
* @param candidates The normalized evidence items to combine.
|
|
2186
|
-
* @returns A frozen deterministic evidence collection.
|
|
2187
|
-
*/
|
|
2188
|
-
var normalizeRuntimeAdapterEvidence = (candidates) => {
|
|
2189
|
-
const evidence = /* @__PURE__ */ new Map();
|
|
2190
|
-
for (const item of candidates) evidence.set(serializeEvidence(item), item);
|
|
2191
|
-
return freezeRecursively([...evidence.values()].sort(compareEvidence));
|
|
2192
|
-
};
|
|
2193
|
-
/**
|
|
2194
|
-
* Validates and normalizes one untrusted runtime adapter result.
|
|
2195
|
-
* @param candidate The result returned by the adapter implementation.
|
|
2196
|
-
* @param context The invoking adapter scope, project, reader, limits, and signal.
|
|
2197
|
-
* @returns A promise resolving to frozen deterministic evidence and diagnostics.
|
|
2198
|
-
* @throws
|
|
2199
|
-
* - INVALID_REPOSITORY_PATH: An adapter repository reference path is invalid.
|
|
2200
|
-
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
2201
|
-
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
2202
|
-
* - SNAPSHOT_CHANGED: The repository snapshot changed during validation.
|
|
2203
|
-
* - INVALID_SOURCE_DATA: The repository reader returned invalid contract data.
|
|
2204
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core or repository resource limit was exceeded.
|
|
2205
|
-
* - ABORTED: Adapter validation or a repository operation was aborted.
|
|
2206
|
-
* - ADAPTER_EXECUTION_FAILED: The adapter result violates its public contract.
|
|
2207
|
-
*/
|
|
2208
|
-
var validateRuntimeAdapterResult = async (candidate, context, outputCounts) => {
|
|
2209
|
-
let diagnostics;
|
|
2210
|
-
let evidence;
|
|
2211
|
-
let validationState;
|
|
2212
|
-
try {
|
|
2213
|
-
if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, ADAPTER_RESULT_KEYS)) return invalidAdapterResult(context.adapterId);
|
|
2214
|
-
const evidenceValue = candidate["evidence"];
|
|
2215
|
-
const diagnosticsValue = candidate["diagnostics"];
|
|
2216
|
-
if (!Array.isArray(evidenceValue) || !Array.isArray(diagnosticsValue)) return invalidAdapterResult(context.adapterId);
|
|
2217
|
-
const evidenceCandidates = evidenceValue;
|
|
2218
|
-
const diagnosticCandidates = diagnosticsValue;
|
|
2219
|
-
registerRawOutput(outputCounts, "evidence", evidenceCandidates.length, context);
|
|
2220
|
-
registerRawOutput(outputCounts, "diagnostics", diagnosticCandidates.length, context);
|
|
2221
|
-
validationState = {
|
|
2222
|
-
...context,
|
|
2223
|
-
agentsById: new Map(context.agents.map((agent) => [agent.id, agent])),
|
|
2224
|
-
decisionIds: new Set(context.project.decisions.map(({ decision }) => decision.id))
|
|
446
|
+
digest: mirror.digest,
|
|
447
|
+
kind: "mirror",
|
|
448
|
+
path: mirror.path,
|
|
449
|
+
scalarLength: mirror.scalarLength
|
|
2225
450
|
};
|
|
2226
|
-
diagnostics = diagnosticCandidates.map((diagnostic) => normalizeDiagnostic(diagnostic, validationState));
|
|
2227
|
-
evidence = normalizeRuntimeAdapterEvidence(evidenceCandidates.map((evidenceCandidate) => normalizeEvidence(evidenceCandidate, validationState)));
|
|
2228
|
-
} catch (error) {
|
|
2229
|
-
if (error instanceof CoreOperationException && error.code === "RESOURCE_LIMIT_EXCEEDED") throw error;
|
|
2230
|
-
return invalidAdapterResult(context.adapterId);
|
|
2231
|
-
}
|
|
2232
|
-
try {
|
|
2233
|
-
await validateEvidenceReferences(evidence, validationState);
|
|
2234
|
-
return freezeRecursively({
|
|
2235
|
-
diagnostics: normalizeDiagnostics(diagnostics),
|
|
2236
|
-
evidence
|
|
2237
|
-
});
|
|
2238
|
-
} catch (error) {
|
|
2239
|
-
if (error instanceof RepositoryPathException || error instanceof RepositorySourceException || error instanceof CoreOperationException) throw error;
|
|
2240
|
-
return invalidAdapterResult(context.adapterId);
|
|
2241
451
|
}
|
|
2242
452
|
};
|
|
453
|
+
/** Creates the content-free summary for one validated project snapshot. */
|
|
454
|
+
var createProjectSummary = (project) => ({
|
|
455
|
+
counts: {
|
|
456
|
+
agents: project.agents.length,
|
|
457
|
+
context: project.context.length,
|
|
458
|
+
decisions: project.decisions.length,
|
|
459
|
+
mirrors: project.agents.reduce((count, agent) => count + agent.mirrors.length, 0),
|
|
460
|
+
runtimes: project.runtimes.length,
|
|
461
|
+
unresolved: project.agents.reduce((count, agent) => count + Object.keys(agent.declaration.unresolved ?? {}).length, Object.keys(project.unresolved).length)
|
|
462
|
+
},
|
|
463
|
+
manifestDigest: project.manifest.asset.digest,
|
|
464
|
+
manifestPath: project.manifest.asset.path,
|
|
465
|
+
projectDigest: project.project.digest,
|
|
466
|
+
projectPath: project.project.path
|
|
467
|
+
});
|
|
2243
468
|
//#endregion
|
|
2244
|
-
//#region src/
|
|
2245
|
-
/**
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
*/
|
|
2253
|
-
var inspectCustomRuntimeRelationships = (context) => {
|
|
2254
|
-
const collector = createRuntimeAdapterResultCollector(context);
|
|
2255
|
-
const { bindings, tools, skills } = context.agent.declaration;
|
|
2256
|
-
const add = (reference, relationship, entity = {}) => {
|
|
2257
|
-
if (reference === void 0) return;
|
|
2258
|
-
collector.diagnostics.add(() => ({
|
|
2259
|
-
code: "CUSTOM_RUNTIME_RELATIONSHIP_UNVERIFIED",
|
|
2260
|
-
details: {
|
|
2261
|
-
reason: "unsupported-source-pattern",
|
|
2262
|
-
relationship
|
|
2263
|
-
},
|
|
2264
|
-
entity: {
|
|
2265
|
-
adapterId: "custom",
|
|
2266
|
-
agentId: context.agent.id,
|
|
2267
|
-
...entity
|
|
2268
|
-
},
|
|
2269
|
-
message: "The declared runtime relationship could not be verified.",
|
|
2270
|
-
path: reference.path,
|
|
2271
|
-
pointer: null,
|
|
2272
|
-
range: null,
|
|
2273
|
-
severity: "warning",
|
|
2274
|
-
source: "custom"
|
|
2275
|
-
}));
|
|
2276
|
-
};
|
|
2277
|
-
add(bindings?.runtimeAgent, "runtime-agent");
|
|
2278
|
-
add(bindings?.instructionLoader, "instruction-loader");
|
|
2279
|
-
add(bindings?.inputSchema, "agent-input-schema");
|
|
2280
|
-
add(bindings?.outputSchema, "agent-output-schema");
|
|
2281
|
-
for (const [variableId, reference] of Object.entries(bindings?.variableProviders ?? {})) add(reference, "variable-provider", { variableId });
|
|
2282
|
-
for (const [capabilityId, tool] of Object.entries(tools ?? {})) {
|
|
2283
|
-
const entity = {
|
|
2284
|
-
capabilityId,
|
|
2285
|
-
capabilityKind: "tool"
|
|
2286
|
-
};
|
|
2287
|
-
add(tool.implementation, "tool-implementation", entity);
|
|
2288
|
-
add(tool.registration, "tool-registration", entity);
|
|
2289
|
-
add(tool.inputSchema, "tool-input-schema", entity);
|
|
2290
|
-
add(tool.outputSchema, "tool-output-schema", entity);
|
|
2291
|
-
}
|
|
2292
|
-
for (const [capabilityId, skill] of Object.entries(skills ?? {})) {
|
|
2293
|
-
const entity = {
|
|
2294
|
-
capabilityId,
|
|
2295
|
-
capabilityKind: "skill"
|
|
2296
|
-
};
|
|
2297
|
-
add(skill.implementation, "skill-implementation", entity);
|
|
2298
|
-
add(skill.registration, "skill-registration", entity);
|
|
2299
|
-
}
|
|
2300
|
-
return Promise.resolve(collector.finalize());
|
|
2301
|
-
};
|
|
469
|
+
//#region src/binding-coverage/index.ts
|
|
470
|
+
/** Counts every declared, existing binding by its actual export-check outcome. */
|
|
471
|
+
var countBindingCoverage = (coverage) => ({
|
|
472
|
+
bindings: coverage.length,
|
|
473
|
+
exportsPassed: coverage.filter((record) => record.exportCheck === "passed").length,
|
|
474
|
+
exportsFailed: coverage.filter((record) => record.exportCheck === "failed").length,
|
|
475
|
+
exportsNotChecked: coverage.filter((record) => record.exportCheck === "not-checked").length
|
|
476
|
+
});
|
|
2302
477
|
//#endregion
|
|
2303
|
-
//#region src/
|
|
2304
|
-
var
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
kind: "ambiguous"
|
|
2320
|
-
});
|
|
2321
|
-
continue;
|
|
2322
|
-
}
|
|
2323
|
-
candidates.set(key, {
|
|
2324
|
-
agent,
|
|
2325
|
-
kind: "matched",
|
|
2326
|
-
resolved: freezeRecursively({
|
|
2327
|
-
declaration: agent.declaration,
|
|
2328
|
-
description: agent.description,
|
|
2329
|
-
handoffDescription: agent.handoffDescription,
|
|
2330
|
-
id: agent.id
|
|
2331
|
-
})
|
|
2332
|
-
});
|
|
2333
|
-
}
|
|
2334
|
-
return candidates;
|
|
2335
|
-
};
|
|
2336
|
-
var invokeAdapter = async (adapter, agent, agentBindings, project, session, options, outputCounts, signal) => {
|
|
2337
|
-
const scopedAgent = freezeRecursively(agent);
|
|
2338
|
-
const resolvedAgents = /* @__PURE__ */ new Map([[scopedAgent.id, scopedAgent]]);
|
|
2339
|
-
const repository = session.adapterRepository;
|
|
2340
|
-
const resolveAgent = (reference) => {
|
|
2341
|
-
const resolution = agentBindings.get(getRuntimeBindingKey(reference));
|
|
2342
|
-
if (resolution === void 0) return Object.freeze({ kind: "absent" });
|
|
2343
|
-
if (resolution.kind === "ambiguous") return Object.freeze({
|
|
2344
|
-
candidateCount: resolution.candidateCount,
|
|
2345
|
-
kind: "ambiguous"
|
|
2346
|
-
});
|
|
2347
|
-
resolvedAgents.set(resolution.agent.id, resolution.agent);
|
|
2348
|
-
return Object.freeze({
|
|
2349
|
-
agent: resolution.resolved,
|
|
2350
|
-
kind: "matched"
|
|
2351
|
-
});
|
|
2352
|
-
};
|
|
2353
|
-
const context = Object.freeze({
|
|
2354
|
-
agent: scopedAgent,
|
|
2355
|
-
outputBudget: createRuntimeAdapterOutputBudget(outputCounts, options.limits),
|
|
2356
|
-
repository,
|
|
2357
|
-
resolveAgent,
|
|
2358
|
-
...signal === void 0 ? {} : { signal }
|
|
2359
|
-
});
|
|
2360
|
-
let candidate;
|
|
2361
|
-
try {
|
|
2362
|
-
session.throwIfAborted();
|
|
2363
|
-
candidate = await adapter.inspect(context);
|
|
2364
|
-
session.throwIfAborted();
|
|
2365
|
-
} catch (error) {
|
|
2366
|
-
session.throwIfAborted();
|
|
2367
|
-
if (isInspectionBoundaryFailure(error)) throw error;
|
|
2368
|
-
throw new CoreOperationException({
|
|
2369
|
-
adapterId: adapter.id,
|
|
2370
|
-
cause: error,
|
|
2371
|
-
code: "ADAPTER_EXECUTION_FAILED",
|
|
2372
|
-
operation: "validate-project"
|
|
2373
|
-
});
|
|
2374
|
-
}
|
|
2375
|
-
return validateRuntimeAdapterResult(candidate, {
|
|
2376
|
-
adapterId: adapter.id,
|
|
2377
|
-
agents: [...resolvedAgents.values()],
|
|
2378
|
-
limits: options.limits,
|
|
2379
|
-
project,
|
|
2380
|
-
repository: session.adapterRepository,
|
|
2381
|
-
...signal === void 0 ? {} : { signal }
|
|
2382
|
-
}, outputCounts);
|
|
2383
|
-
};
|
|
2384
|
-
/**
|
|
2385
|
-
* Invokes every applicable configured adapter in canonical ID order.
|
|
2386
|
-
* @param project The complete frozen universal project index.
|
|
2387
|
-
* @param session The shared inspection reader, cache, and resource budget.
|
|
2388
|
-
* @param options The immutable Core adapter registry and resource limits.
|
|
2389
|
-
* @param signal Optional cancellation shared by the complete inspection.
|
|
2390
|
-
* @returns A promise resolving to normalized evidence and adapter diagnostics.
|
|
2391
|
-
* @throws
|
|
2392
|
-
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
2393
|
-
* - ENTRY_NOT_FOUND: The requested repository entry was not found.
|
|
2394
|
-
* - ENTRY_NOT_FILE: The requested repository entry is not a file.
|
|
2395
|
-
* - ENTRY_NOT_DIRECTORY: The requested repository entry is not a directory.
|
|
2396
|
-
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
2397
|
-
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
2398
|
-
* - PROVIDER_INCOMPLETE: The repository provider cannot expose a complete result.
|
|
2399
|
-
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
2400
|
-
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
2401
|
-
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
2402
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
2403
|
-
* - ABORTED: The repository operation was aborted.
|
|
2404
|
-
* - ABORTED: The Core operation was aborted.
|
|
2405
|
-
* - ADAPTER_EXECUTION_FAILED: A runtime adapter failed during inspection.
|
|
2406
|
-
*/
|
|
2407
|
-
var inspectRuntimeAdapters = async (project, session, options, signal) => {
|
|
2408
|
-
const evidence = [];
|
|
2409
|
-
const diagnostics = [];
|
|
2410
|
-
const outputCounts = {
|
|
2411
|
-
diagnostics: 0,
|
|
2412
|
-
evidence: 0
|
|
2413
|
-
};
|
|
2414
|
-
const agentsByRuntimeId = /* @__PURE__ */ new Map();
|
|
2415
|
-
for (const agent of project.agents) {
|
|
2416
|
-
const runtimeAgents = agentsByRuntimeId.get(agent.declaration.runtime.id);
|
|
2417
|
-
if (runtimeAgents === void 0) agentsByRuntimeId.set(agent.declaration.runtime.id, [agent]);
|
|
2418
|
-
else runtimeAgents.push(agent);
|
|
2419
|
-
}
|
|
2420
|
-
const inspections = [...options.adapters, {
|
|
2421
|
-
id: "custom",
|
|
2422
|
-
inspect: inspectCustomRuntimeRelationships
|
|
2423
|
-
}].sort((left, right) => left.id < right.id ? -1 : left.id > right.id ? 1 : 0);
|
|
2424
|
-
for (const adapter of inspections) {
|
|
2425
|
-
const agents = agentsByRuntimeId.get(adapter.id) ?? [];
|
|
2426
|
-
const agentBindings = createRuntimeAgentBindingIndex(agents);
|
|
2427
|
-
for (const agent of agents) {
|
|
2428
|
-
const result = await invokeAdapter(adapter, agent, agentBindings, project, session, options, outputCounts, signal);
|
|
2429
|
-
evidence.push(...result.evidence);
|
|
2430
|
-
diagnostics.push(...result.diagnostics);
|
|
2431
|
-
}
|
|
2432
|
-
}
|
|
2433
|
-
return freezeRecursively({
|
|
2434
|
-
diagnostics: normalizeDiagnostics(diagnostics),
|
|
2435
|
-
evidence: normalizeRuntimeAdapterEvidence(evidence)
|
|
2436
|
-
});
|
|
478
|
+
//#region src/retained-memory/index.ts
|
|
479
|
+
var ledgers = /* @__PURE__ */ new WeakMap();
|
|
480
|
+
/** Registers the sole memory owner for one internal reader. */
|
|
481
|
+
var registerRetainedMemory = (reader, ledger) => {
|
|
482
|
+
if (ledgers.has(reader)) throw new TypeError("The inspection reader is already registered.");
|
|
483
|
+
ledgers.set(reader, ledger);
|
|
484
|
+
};
|
|
485
|
+
/** Returns the ledger shared by all phases of a repository inspection. */
|
|
486
|
+
var getRetainedMemory = (reader) => {
|
|
487
|
+
const ledger = ledgers.get(reader);
|
|
488
|
+
if (ledger === void 0) throw new TypeError("The inspection reader has no retained-memory ledger.");
|
|
489
|
+
return ledger;
|
|
490
|
+
};
|
|
491
|
+
/** Reserves retained coverage in production sessions and leaves standalone file-check readers untracked. */
|
|
492
|
+
var reserveRetainedBytesIfTracked = (reader, bytes) => {
|
|
493
|
+
ledgers.get(reader)?.reserve(bytes);
|
|
2437
494
|
};
|
|
2438
495
|
//#endregion
|
|
2439
496
|
//#region src/repository-inspection-session/index.ts
|
|
@@ -2497,7 +554,7 @@ var createSourceOptions = (sessionSignal, operationSignal) => {
|
|
|
2497
554
|
* @param signal Optional cancellation shared by every inspection operation.
|
|
2498
555
|
* @returns A session that pages source metadata and range-reads bounded canonical files.
|
|
2499
556
|
* @throws
|
|
2500
|
-
* - ABORTED:
|
|
557
|
+
* - ABORTED: The Core operation was aborted.
|
|
2501
558
|
*/
|
|
2502
559
|
var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
2503
560
|
const seenPaths = /* @__PURE__ */ new Set();
|
|
@@ -2505,13 +562,6 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
2505
562
|
let peakRetainedBytes = 0;
|
|
2506
563
|
let retainedBytes = 0;
|
|
2507
564
|
let totalBytesRead = 0;
|
|
2508
|
-
const adapterLimits = Object.freeze({
|
|
2509
|
-
maxEntries: limits.maxEntries,
|
|
2510
|
-
maxFileBytes: limits.maxFileBytes,
|
|
2511
|
-
maxPageBytes: Math.min(SOURCE_PAGE_BYTES, limits.maxFileBytes),
|
|
2512
|
-
maxPageEntries: Math.min(SOURCE_PAGE_ENTRIES, limits.maxEntries),
|
|
2513
|
-
maxTotalBytesRead: limits.maxTotalBytesRead
|
|
2514
|
-
});
|
|
2515
565
|
const createAbortedException = (abortedSignal) => {
|
|
2516
566
|
return new CoreOperationException({
|
|
2517
567
|
cause: abortedSignal.reason,
|
|
@@ -2585,7 +635,8 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
2585
635
|
} while (true);
|
|
2586
636
|
} };
|
|
2587
637
|
};
|
|
2588
|
-
const loadFile = async (path, operationSignal) => {
|
|
638
|
+
const loadFile = async (path, operationSignal, isSource = false) => {
|
|
639
|
+
const multiplier = isSource ? 1 : CANONICAL_BYTE_RETENTION_MULTIPLIER;
|
|
2589
640
|
const fileLimit = path === MANIFEST_PATH$3 ? "maxManifestBytes" : "maxFileBytes";
|
|
2590
641
|
const availableRetainedBytes = limits.maxRetainedBytes - retainedBytes;
|
|
2591
642
|
if (availableRetainedBytes < 1) return throwResourceLimitExceeded("maxRetainedBytes", limits.maxRetainedBytes, retainedBytes + 1);
|
|
@@ -2601,15 +652,15 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
2601
652
|
if (firstPage.totalBytes > limits[fileLimit]) return throwResourceLimitExceeded(fileLimit, limits[fileLimit], firstPage.totalBytes);
|
|
2602
653
|
const firstPageBytes = firstPage.bytes.byteLength;
|
|
2603
654
|
const retainedBytesAvailableForCanonicalContent = limits.maxRetainedBytes - retainedBytes - firstPageBytes;
|
|
2604
|
-
if (retainedBytesAvailableForCanonicalContent < 0 || firstPage.totalBytes > Math.floor(retainedBytesAvailableForCanonicalContent /
|
|
2605
|
-
const projectedUsage = retainedBytes + firstPageBytes + firstPage.totalBytes *
|
|
655
|
+
if (retainedBytesAvailableForCanonicalContent < 0 || firstPage.totalBytes > Math.floor(retainedBytesAvailableForCanonicalContent / multiplier)) {
|
|
656
|
+
const projectedUsage = retainedBytes + firstPageBytes + firstPage.totalBytes * multiplier;
|
|
2606
657
|
return throwResourceLimitExceeded("maxRetainedBytes", limits.maxRetainedBytes, Number.isSafeInteger(projectedUsage) ? projectedUsage : Number.MAX_SAFE_INTEGER);
|
|
2607
658
|
}
|
|
2608
659
|
reserveReadBytes(firstPage.totalBytes);
|
|
2609
|
-
const canonicalRetainedBytes = firstPage.totalBytes *
|
|
660
|
+
const canonicalRetainedBytes = firstPage.totalBytes * multiplier;
|
|
2610
661
|
observeTransientBytes(canonicalRetainedBytes + firstPageBytes);
|
|
2611
662
|
reserveRetainedBytes(canonicalRetainedBytes);
|
|
2612
|
-
canonicalBytes += firstPage.totalBytes;
|
|
663
|
+
if (!isSource) canonicalBytes += firstPage.totalBytes;
|
|
2613
664
|
const content = new Uint8Array(firstPage.totalBytes);
|
|
2614
665
|
let offset = 0;
|
|
2615
666
|
let page = firstPage;
|
|
@@ -2636,14 +687,14 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
2636
687
|
const awaitWithCancellation = async (promise, operationSignal) => {
|
|
2637
688
|
const callerSignal = createSourceOptions(signal, operationSignal)?.signal;
|
|
2638
689
|
if (callerSignal === void 0) return promise;
|
|
2639
|
-
if (callerSignal.aborted) throw createAbortedException(callerSignal);
|
|
2640
690
|
return new Promise((resolve, reject) => {
|
|
2641
691
|
const cleanup = () => callerSignal.removeEventListener("abort", abort);
|
|
2642
692
|
const abort = () => {
|
|
2643
693
|
cleanup();
|
|
2644
694
|
reject(createAbortedException(callerSignal));
|
|
2645
695
|
};
|
|
2646
|
-
callerSignal.
|
|
696
|
+
if (callerSignal.aborted) abort();
|
|
697
|
+
else callerSignal.addEventListener("abort", abort, { once: true });
|
|
2647
698
|
promise.then((result) => {
|
|
2648
699
|
cleanup();
|
|
2649
700
|
resolve(result);
|
|
@@ -2667,90 +718,45 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
2667
718
|
throwIfSignalAborted(options?.signal);
|
|
2668
719
|
return content.slice();
|
|
2669
720
|
};
|
|
2670
|
-
const
|
|
2671
|
-
const prefix = options.prefix === void 0 ? REPOSITORY_ROOT : parseRepositoryPath(options.prefix);
|
|
2672
|
-
registerPath(prefix);
|
|
2673
|
-
if (!Number.isSafeInteger(options.maxEntries) || options.maxEntries < 1 || options.maxEntries > adapterLimits.maxPageEntries) return throwResourceLimitExceeded("maxEntries", adapterLimits.maxPageEntries, options.maxEntries);
|
|
2674
|
-
throwIfSignalAborted(options.signal);
|
|
2675
|
-
const page = await repository.listEntriesPage({
|
|
2676
|
-
...options.cursor === void 0 ? {} : { cursor: options.cursor },
|
|
2677
|
-
maxEntries: options.maxEntries,
|
|
2678
|
-
prefix,
|
|
2679
|
-
...createSourceOptions(signal, options.signal) ?? {}
|
|
2680
|
-
});
|
|
2681
|
-
throwIfSignalAborted(options.signal);
|
|
2682
|
-
if (page.snapshot.id !== repository.snapshot.id || page.entries.length > options.maxEntries || page.entries.length === 0 && !page.isComplete || (page.isComplete ? page.nextCursor !== null : page.nextCursor === null)) return invalidSourceData$3("list-entries-page", prefix);
|
|
2683
|
-
let previousPath = null;
|
|
2684
|
-
const entries = page.entries.map((candidate) => {
|
|
2685
|
-
const entry = copyReaderEntry$1(candidate, "list-entries-page", prefix);
|
|
2686
|
-
if (!isStrictDescendant(entry.path, prefix) || previousPath !== null && compareRepositoryPaths(previousPath, entry.path) >= 0) return invalidSourceData$3("list-entries-page", entry.path);
|
|
2687
|
-
previousPath = entry.path;
|
|
2688
|
-
registerPath(entry.path);
|
|
2689
|
-
return entry;
|
|
2690
|
-
});
|
|
2691
|
-
return Object.freeze({
|
|
2692
|
-
entries: Object.freeze(entries),
|
|
2693
|
-
isComplete: page.isComplete,
|
|
2694
|
-
nextCursor: page.nextCursor,
|
|
2695
|
-
snapshot: repository.snapshot
|
|
2696
|
-
});
|
|
2697
|
-
};
|
|
2698
|
-
const readAdapterFilePage = async (path, options) => {
|
|
2699
|
-
const parsedPath = parseRepositoryPath(path);
|
|
2700
|
-
if (!Number.isSafeInteger(options.offset) || options.offset < 0 || !Number.isSafeInteger(options.maxBytes) || options.maxBytes < 1 || options.maxBytes > adapterLimits.maxPageBytes) return invalidSourceData$3("read-file-page", parsedPath);
|
|
2701
|
-
throwIfSignalAborted(options.signal);
|
|
2702
|
-
registerPath(parsedPath);
|
|
2703
|
-
const reservedBytes = Math.min(options.maxBytes, limits.maxTotalBytesRead - totalBytesRead);
|
|
2704
|
-
if (reservedBytes < 1) return throwResourceLimitExceeded("maxTotalBytesRead", limits.maxTotalBytesRead, totalBytesRead + 1);
|
|
2705
|
-
observeTransientBytes(reservedBytes);
|
|
2706
|
-
reserveReadBytes(reservedBytes);
|
|
2707
|
-
let page;
|
|
2708
|
-
try {
|
|
2709
|
-
page = await repository.readFilePage(parsedPath, {
|
|
2710
|
-
maxBytes: reservedBytes,
|
|
2711
|
-
offset: options.offset,
|
|
2712
|
-
...createSourceOptions(signal, options.signal) ?? {}
|
|
2713
|
-
});
|
|
2714
|
-
} catch (error) {
|
|
2715
|
-
totalBytesRead -= reservedBytes;
|
|
2716
|
-
throw error;
|
|
2717
|
-
}
|
|
2718
|
-
throwIfSignalAborted(options.signal);
|
|
2719
|
-
if (page.snapshot.id !== repository.snapshot.id || page.offset !== options.offset || !(page.bytes instanceof Uint8Array) || !Number.isSafeInteger(page.totalBytes) || page.totalBytes < 0 || page.totalBytes > limits.maxFileBytes || page.bytes.byteLength > reservedBytes || page.bytes.byteLength > page.totalBytes - page.offset || page.bytes.byteLength === 0 && !page.isComplete || (page.isComplete ? page.nextOffset !== null || page.offset + page.bytes.byteLength !== page.totalBytes : page.nextOffset !== page.offset + page.bytes.byteLength)) {
|
|
2720
|
-
totalBytesRead -= reservedBytes;
|
|
2721
|
-
return invalidSourceData$3("read-file-page", parsedPath);
|
|
2722
|
-
}
|
|
2723
|
-
totalBytesRead -= reservedBytes - page.bytes.byteLength;
|
|
2724
|
-
return Object.freeze({
|
|
2725
|
-
bytes: page.bytes.slice(),
|
|
2726
|
-
isComplete: page.isComplete,
|
|
2727
|
-
nextOffset: page.nextOffset,
|
|
2728
|
-
offset: page.offset,
|
|
2729
|
-
snapshot: repository.snapshot,
|
|
2730
|
-
totalBytes: page.totalBytes
|
|
2731
|
-
});
|
|
2732
|
-
};
|
|
2733
|
-
const adapterRepository = Object.freeze({
|
|
721
|
+
const reader = Object.freeze({
|
|
2734
722
|
getEntry,
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
723
|
+
iterateEntries,
|
|
724
|
+
readCompleteFile
|
|
725
|
+
});
|
|
726
|
+
registerRetainedMemory(reader, {
|
|
727
|
+
reserve: reserveRetainedBytes,
|
|
728
|
+
tryReserve: (bytes) => {
|
|
729
|
+
if (!Number.isSafeInteger(bytes) || bytes < 0 || bytes > limits.maxRetainedBytes - retainedBytes) return false;
|
|
730
|
+
reserveRetainedBytes(bytes);
|
|
731
|
+
return true;
|
|
732
|
+
},
|
|
733
|
+
release: (bytes) => {
|
|
734
|
+
if (!Number.isSafeInteger(bytes) || bytes < 0 || bytes > retainedBytes) throw new TypeError("The retained-memory release is invalid.");
|
|
735
|
+
retainedBytes -= bytes;
|
|
736
|
+
},
|
|
737
|
+
readSourceFile: async (path) => {
|
|
738
|
+
throwIfSignalAborted();
|
|
739
|
+
registerPath(path);
|
|
740
|
+
const bytes = await awaitWithCancellation(loadFile(path, void 0, true));
|
|
741
|
+
throwIfSignalAborted();
|
|
742
|
+
let isReleased = false;
|
|
743
|
+
return {
|
|
744
|
+
bytes,
|
|
745
|
+
release: () => {
|
|
746
|
+
if (!isReleased) retainedBytes -= bytes.byteLength;
|
|
747
|
+
isReleased = true;
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
}
|
|
2739
751
|
});
|
|
2740
|
-
registerRuntimeAdapterRetainedByteReservation(adapterRepository, reserveRetainedBytes);
|
|
2741
752
|
return Object.freeze({
|
|
2742
|
-
adapterRepository,
|
|
2743
753
|
getResourceUsage: () => Object.freeze({
|
|
2744
754
|
canonicalBytes,
|
|
2745
755
|
peakRetainedBytes,
|
|
2746
756
|
retainedBytes,
|
|
2747
757
|
totalBytesRead
|
|
2748
758
|
}),
|
|
2749
|
-
reader
|
|
2750
|
-
getEntry,
|
|
2751
|
-
iterateEntries,
|
|
2752
|
-
readCompleteFile
|
|
2753
|
-
}),
|
|
759
|
+
reader,
|
|
2754
760
|
throwIfAborted: throwIfSignalAborted
|
|
2755
761
|
});
|
|
2756
762
|
};
|
|
@@ -2778,7 +784,7 @@ var findNonblankLine = (lines, startIndex) => {
|
|
|
2778
784
|
var validateAgentDescription = (asset, agentId, kind, limits) => {
|
|
2779
785
|
const diagnostics = createCoreDiagnosticCollector(limits, "validate-project");
|
|
2780
786
|
const value = trimRepositoryFormatWhitespace(asset.content);
|
|
2781
|
-
const scalarLength = countUnicodeScalars
|
|
787
|
+
const scalarLength = countUnicodeScalars(value);
|
|
2782
788
|
const code = kind === "description" ? "MOLDEA_AGENT_DESCRIPTION_INVALID" : "MOLDEA_AGENT_HANDOFF_DESCRIPTION_INVALID";
|
|
2783
789
|
if (scalarLength === 0) diagnostics.add({
|
|
2784
790
|
code,
|
|
@@ -3697,18 +1703,20 @@ var sortDecisions = (decisions) => {
|
|
|
3697
1703
|
* Reads, parses, and validates every discovered decision through one repository snapshot.
|
|
3698
1704
|
* @param repository The coherent source-neutral repository reader.
|
|
3699
1705
|
* @param paths The decision candidates retained by canonical discovery.
|
|
3700
|
-
* @param options The immutable Core
|
|
1706
|
+
* @param options The immutable Core limit snapshot.
|
|
3701
1707
|
* @param signal Optional cancellation forwarded to every repository read.
|
|
3702
1708
|
* @returns A deeply immutable internal decision set and its deterministic diagnostics.
|
|
3703
1709
|
* @throws
|
|
3704
|
-
* - ENTRY_NOT_FOUND:
|
|
3705
|
-
* - ENTRY_NOT_FILE:
|
|
1710
|
+
* - ENTRY_NOT_FOUND: The requested repository entry was not found.
|
|
1711
|
+
* - ENTRY_NOT_FILE: The requested repository entry is not a file.
|
|
3706
1712
|
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
3707
1713
|
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
3708
|
-
* - SNAPSHOT_CHANGED: The repository snapshot changed during
|
|
3709
|
-
* - INVALID_SOURCE_DATA: The repository
|
|
3710
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core
|
|
3711
|
-
* -
|
|
1714
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
1715
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
1716
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1717
|
+
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
1718
|
+
* - ABORTED: The Core operation was aborted.
|
|
1719
|
+
* - ABORTED: The repository operation was aborted.
|
|
3712
1720
|
*/
|
|
3713
1721
|
var readDecisionGraph = async (repository, paths, options, signal) => {
|
|
3714
1722
|
options = createCoreOperationOptionsSnapshot(options);
|
|
@@ -3771,56 +1779,396 @@ var validateDecisionRelationship = (referencedPath, pointer, context, agentId) =
|
|
|
3771
1779
|
path: context.manifestPath,
|
|
3772
1780
|
pointer
|
|
3773
1781
|
});
|
|
3774
|
-
return;
|
|
1782
|
+
return;
|
|
1783
|
+
}
|
|
1784
|
+
const parsedDecision = context.parsedDecisionsByPath.get(referencedPath);
|
|
1785
|
+
if (parsedDecision === void 0 || parsedDecision.status === "accepted") return;
|
|
1786
|
+
context.collector.add({
|
|
1787
|
+
code: "MOLDEA_DECISION_RELATIONSHIP_INACTIVE",
|
|
1788
|
+
details: {
|
|
1789
|
+
referencedPath,
|
|
1790
|
+
targetStatus: parsedDecision.status
|
|
1791
|
+
},
|
|
1792
|
+
entity: createDecisionEntity(referencedPath, agentId),
|
|
1793
|
+
path: context.manifestPath,
|
|
1794
|
+
pointer
|
|
1795
|
+
});
|
|
1796
|
+
};
|
|
1797
|
+
/**
|
|
1798
|
+
* Validates manifest and agent relationships against canonical discovery and parsed decisions.
|
|
1799
|
+
* @param manifestPath The canonical manifest path used for relationship diagnostics.
|
|
1800
|
+
* @param manifest The normalized manifest contract to validate.
|
|
1801
|
+
* @param discovery The canonical repository discovery result.
|
|
1802
|
+
* @param decisions The successfully parsed canonical decisions.
|
|
1803
|
+
* @param limits The resource limits applied to emitted diagnostics.
|
|
1804
|
+
* @returns The frozen deterministic relationship diagnostics.
|
|
1805
|
+
* @throws
|
|
1806
|
+
* - RESOURCE_LIMIT_EXCEEDED: The repository-level diagnostic budget was exceeded.
|
|
1807
|
+
*/
|
|
1808
|
+
var validateManifestRelationships = (manifestPath, manifest, discovery, decisions, limits) => {
|
|
1809
|
+
const collector = createCoreDiagnosticCollector(limits, "validate-project");
|
|
1810
|
+
const validAgentContextPaths = new Set(discovery.inventory.context);
|
|
1811
|
+
const validTopLevelContextPaths = new Set(validAgentContextPaths);
|
|
1812
|
+
if (discovery.inventory.project !== null) validTopLevelContextPaths.add(discovery.inventory.project);
|
|
1813
|
+
const validationContext = {
|
|
1814
|
+
blockedPaths: new Set(discovery.diagnostics.flatMap((diagnostic) => diagnostic.path === null ? [] : [diagnostic.path])),
|
|
1815
|
+
collector,
|
|
1816
|
+
discoveredDecisionPaths: new Set(discovery.inventory.decisions),
|
|
1817
|
+
manifestPath,
|
|
1818
|
+
parsedDecisionsByPath: new Map(decisions.map((decision) => [decision.path, decision])),
|
|
1819
|
+
validAgentContextPaths,
|
|
1820
|
+
validTopLevelContextPaths
|
|
1821
|
+
};
|
|
1822
|
+
for (const referencedPathValue of Object.keys(manifest.context ?? {}).sort(compareExactStrings)) validateContextRelationship(parseRepositoryPath(referencedPathValue), `/context/${escapeJsonPointerSegment(referencedPathValue)}`, validationContext.validTopLevelContextPaths, validationContext);
|
|
1823
|
+
for (const referencedPathValue of Object.keys(manifest.decisions ?? {}).sort(compareExactStrings)) validateDecisionRelationship(parseRepositoryPath(referencedPathValue), `/decisions/${escapeJsonPointerSegment(referencedPathValue)}`, validationContext);
|
|
1824
|
+
for (const agentId of Object.keys(manifest.agents ?? {}).sort(compareExactStrings)) {
|
|
1825
|
+
const agent = manifest.agents?.[agentId];
|
|
1826
|
+
if (agent === void 0) continue;
|
|
1827
|
+
const escapedAgentId = escapeJsonPointerSegment(agentId);
|
|
1828
|
+
for (const referencedPath of [...agent.context ?? []].sort(compareExactStrings)) validateContextRelationship(referencedPath, `/agents/${escapedAgentId}/context`, validationContext.validAgentContextPaths, validationContext, agentId);
|
|
1829
|
+
for (const referencedPath of [...agent.decisions ?? []].sort(compareExactStrings)) validateDecisionRelationship(referencedPath, `/agents/${escapedAgentId}/decisions`, validationContext, agentId);
|
|
1830
|
+
}
|
|
1831
|
+
return collector.finalize();
|
|
1832
|
+
};
|
|
1833
|
+
//#endregion
|
|
1834
|
+
//#region src/integration-validation/parser.ts
|
|
1835
|
+
var START = "<!-- moldea:start -->";
|
|
1836
|
+
var END = "<!-- moldea:end -->";
|
|
1837
|
+
/** Finds one ordered marker pair on complete lines, matching the skill writer's region semantics. */
|
|
1838
|
+
var parseManagedIntegrationRegion = (text) => {
|
|
1839
|
+
const start = text.indexOf(START);
|
|
1840
|
+
const end = text.indexOf(END);
|
|
1841
|
+
if (start < 0 || end < start || text.indexOf(START, start + 21) >= 0 || text.indexOf(END, end + 19) >= 0) return null;
|
|
1842
|
+
const startsLine = (offset) => offset === 0 || offset === 1 && text[0] === "" || text[offset - 1] === "\n";
|
|
1843
|
+
if (!startsLine(start) || !startsLine(end)) return null;
|
|
1844
|
+
const afterStart = start + 21;
|
|
1845
|
+
const lineEnding = text.startsWith("\r\n", afterStart) ? "\r\n" : text[afterStart] === "\n" ? "\n" : null;
|
|
1846
|
+
if (lineEnding === null) return null;
|
|
1847
|
+
const afterEnd = end + 19;
|
|
1848
|
+
const endLength = text.startsWith("\r\n", afterEnd) ? 2 : text[afterEnd] === "\n" ? 1 : 0;
|
|
1849
|
+
if (endLength === 0 && afterEnd !== text.length) return null;
|
|
1850
|
+
return {
|
|
1851
|
+
start,
|
|
1852
|
+
end: afterEnd + endLength,
|
|
1853
|
+
lineEnding
|
|
1854
|
+
};
|
|
1855
|
+
};
|
|
1856
|
+
/**
|
|
1857
|
+
* Extracts the relative installation path from the fixed relevance-gate command without executing it.
|
|
1858
|
+
* @returns The safe installation path or the reason it could not be obtained.
|
|
1859
|
+
*/
|
|
1860
|
+
var parseIntegrationBlock = (text) => {
|
|
1861
|
+
const region = parseManagedIntegrationRegion(text);
|
|
1862
|
+
if (region === null) return {
|
|
1863
|
+
kind: "missing",
|
|
1864
|
+
reason: text.includes(START) || text.includes(END) ? "block-invalid" : "block-missing"
|
|
1865
|
+
};
|
|
1866
|
+
const matches = text.slice(region.start, region.end).matchAll(/^node "<repo-root>\/([^"\r\n]+)\/scripts\/relevance-gate\.mjs"(?:[ \t\r]|$)/gm);
|
|
1867
|
+
const first = matches.next().value;
|
|
1868
|
+
if (first === void 0 || !matches.next().done) return {
|
|
1869
|
+
kind: "missing",
|
|
1870
|
+
reason: "skill-path-missing"
|
|
1871
|
+
};
|
|
1872
|
+
const skillPath = first[1];
|
|
1873
|
+
if (skillPath === void 0 || !/^[A-Za-z0-9._/-]+$/.test(skillPath) || skillPath.startsWith("/") || skillPath.endsWith("/") || skillPath.includes("//") || /(?:^|\/)\.{1,2}(?:\/|$)/.test(skillPath)) return {
|
|
1874
|
+
kind: "missing",
|
|
1875
|
+
reason: "skill-path-invalid"
|
|
1876
|
+
};
|
|
1877
|
+
return {
|
|
1878
|
+
kind: "found",
|
|
1879
|
+
skillPath
|
|
1880
|
+
};
|
|
1881
|
+
};
|
|
1882
|
+
//#endregion
|
|
1883
|
+
//#region src/integration-validation/inspection.ts
|
|
1884
|
+
var AGENTS_PATH = parseRepositoryPath("/AGENTS.md");
|
|
1885
|
+
/**
|
|
1886
|
+
* Reads bounded untrusted text with a reservation for decoding and temporary string copies.
|
|
1887
|
+
* @returns Decoded text or null for invalid UTF-8, with its reservation-release operation.
|
|
1888
|
+
* @throws
|
|
1889
|
+
* - ENTRY_NOT_FOUND: The requested repository entry was not found.
|
|
1890
|
+
* - ENTRY_NOT_FILE: The requested repository entry is not a file.
|
|
1891
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1892
|
+
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
1893
|
+
* - ABORTED: The Core operation was aborted.
|
|
1894
|
+
* - ABORTED: The repository operation was aborted.
|
|
1895
|
+
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
1896
|
+
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
1897
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
1898
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
1899
|
+
*/
|
|
1900
|
+
var readText = async (ledger, path) => {
|
|
1901
|
+
const source = await ledger.readSourceFile(path);
|
|
1902
|
+
const reservation = source.bytes.byteLength * 8;
|
|
1903
|
+
let isReserved = false;
|
|
1904
|
+
try {
|
|
1905
|
+
ledger.reserve(reservation);
|
|
1906
|
+
isReserved = true;
|
|
1907
|
+
let text;
|
|
1908
|
+
try {
|
|
1909
|
+
text = new TextDecoder("utf-8", { fatal: true }).decode(source.bytes);
|
|
1910
|
+
} catch {
|
|
1911
|
+
text = null;
|
|
1912
|
+
}
|
|
1913
|
+
return {
|
|
1914
|
+
text,
|
|
1915
|
+
release: () => ledger.release(reservation)
|
|
1916
|
+
};
|
|
1917
|
+
} catch (error) {
|
|
1918
|
+
if (isReserved) ledger.release(reservation);
|
|
1919
|
+
throw error;
|
|
1920
|
+
} finally {
|
|
1921
|
+
source.release();
|
|
1922
|
+
}
|
|
1923
|
+
};
|
|
1924
|
+
/** Distinguishes missing and non-regular files without an extra entry lookup or following symlinks. */
|
|
1925
|
+
var getAbsentKind = (error) => error instanceof RepositorySourceException ? error.code === "ENTRY_NOT_FOUND" ? "missing" : error.code === "ENTRY_NOT_FILE" ? "non-regular" : null : null;
|
|
1926
|
+
/**
|
|
1927
|
+
* Checks the root integration against its installed asset with at most two reads and two lookups.
|
|
1928
|
+
* @returns Completed content-free integration warnings, never an execution or runtime-wiring claim.
|
|
1929
|
+
* @throws
|
|
1930
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1931
|
+
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
1932
|
+
* - ABORTED: The Core operation was aborted.
|
|
1933
|
+
* - ABORTED: The repository operation was aborted.
|
|
1934
|
+
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
1935
|
+
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
1936
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
1937
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
1938
|
+
*/
|
|
1939
|
+
var inspectCodingAgentIntegration = async (reader, limits, signal) => {
|
|
1940
|
+
const ledger = getRetainedMemory(reader);
|
|
1941
|
+
const collector = createCoreDiagnosticCollector(limits, "validate-project");
|
|
1942
|
+
const report = (code, details) => {
|
|
1943
|
+
collector.add({
|
|
1944
|
+
code,
|
|
1945
|
+
path: AGENTS_PATH,
|
|
1946
|
+
subject: AGENTS_PATH,
|
|
1947
|
+
qualifier: null,
|
|
1948
|
+
entity: { integrationPath: AGENTS_PATH },
|
|
1949
|
+
details
|
|
1950
|
+
});
|
|
1951
|
+
return collector.finalize();
|
|
1952
|
+
};
|
|
1953
|
+
let document;
|
|
1954
|
+
try {
|
|
1955
|
+
document = await readText(ledger, AGENTS_PATH);
|
|
1956
|
+
} catch (error) {
|
|
1957
|
+
const entryKind = getAbsentKind(error);
|
|
1958
|
+
if (entryKind !== null) return report("MOLDEA_INTEGRATION_BLOCK_MISSING", { entryKind });
|
|
1959
|
+
throw error;
|
|
1960
|
+
}
|
|
1961
|
+
try {
|
|
1962
|
+
if (document.text === null) return report("MOLDEA_INTEGRATION_BLOCK_MISSING", {
|
|
1963
|
+
entryKind: "file",
|
|
1964
|
+
reason: "invalid-utf8"
|
|
1965
|
+
});
|
|
1966
|
+
const parsed = parseIntegrationBlock(document.text);
|
|
1967
|
+
if (parsed.kind === "missing") return report(parsed.reason.startsWith("block-") ? "MOLDEA_INTEGRATION_BLOCK_MISSING" : "MOLDEA_INTEGRATION_SKILL_MISSING", {
|
|
1968
|
+
entryKind: "file",
|
|
1969
|
+
reason: parsed.reason
|
|
1970
|
+
});
|
|
1971
|
+
const { skillPath } = parsed;
|
|
1972
|
+
for (const file of ["SKILL.md", "scripts/relevance-gate.mjs"]) {
|
|
1973
|
+
const path = parseRepositoryPath(`/${skillPath}/${file}`);
|
|
1974
|
+
const entry = await reader.getEntry(path, signal === void 0 ? void 0 : { signal });
|
|
1975
|
+
if (entry?.type !== "file") return report("MOLDEA_INTEGRATION_SKILL_MISSING", {
|
|
1976
|
+
referencedPath: `/${skillPath}`,
|
|
1977
|
+
missingFile: path,
|
|
1978
|
+
entryKind: entry?.type ?? "missing"
|
|
1979
|
+
});
|
|
1980
|
+
}
|
|
1981
|
+
const assetPath = parseRepositoryPath(`/${skillPath}/assets/managed-agents-block.md`);
|
|
1982
|
+
let asset;
|
|
1983
|
+
try {
|
|
1984
|
+
asset = await readText(ledger, assetPath);
|
|
1985
|
+
} catch (error) {
|
|
1986
|
+
const entryKind = getAbsentKind(error);
|
|
1987
|
+
if (entryKind !== null) return report("MOLDEA_INTEGRATION_SKILL_MISSING", {
|
|
1988
|
+
referencedPath: `/${skillPath}`,
|
|
1989
|
+
missingFile: assetPath,
|
|
1990
|
+
entryKind
|
|
1991
|
+
});
|
|
1992
|
+
throw error;
|
|
1993
|
+
}
|
|
1994
|
+
try {
|
|
1995
|
+
if (asset.text === null) return report("MOLDEA_INTEGRATION_BLOCK_STALE", {
|
|
1996
|
+
referencedPath: `/${skillPath}`,
|
|
1997
|
+
reason: "invalid-utf8-asset"
|
|
1998
|
+
});
|
|
1999
|
+
const region = parseManagedIntegrationRegion(document.text);
|
|
2000
|
+
let occurrences = 0;
|
|
2001
|
+
let offset = 0;
|
|
2002
|
+
while ((offset = asset.text.indexOf("{{skill-path}}", offset)) !== -1) {
|
|
2003
|
+
occurrences++;
|
|
2004
|
+
offset += 14;
|
|
2005
|
+
}
|
|
2006
|
+
const renderedReservation = (asset.text.length + occurrences * skillPath.length) * 8;
|
|
2007
|
+
ledger.reserve(renderedReservation);
|
|
2008
|
+
try {
|
|
2009
|
+
const expected = asset.text.replaceAll("{{skill-path}}", skillPath).replace(/\r\n?/g, "\n").replaceAll("\n", region.lineEnding);
|
|
2010
|
+
if (document.text.slice(region.start, region.end) !== expected) return report("MOLDEA_INTEGRATION_BLOCK_STALE", { referencedPath: `/${skillPath}` });
|
|
2011
|
+
} finally {
|
|
2012
|
+
ledger.release(renderedReservation);
|
|
2013
|
+
}
|
|
2014
|
+
return collector.finalize();
|
|
2015
|
+
} finally {
|
|
2016
|
+
asset.release();
|
|
2017
|
+
}
|
|
2018
|
+
} finally {
|
|
2019
|
+
document.release();
|
|
2020
|
+
}
|
|
2021
|
+
};
|
|
2022
|
+
//#endregion
|
|
2023
|
+
//#region src/impact-pattern-validation/inspection.ts
|
|
2024
|
+
/** Identifies the canonical document owning an impact relationship. */
|
|
2025
|
+
var getOwner = (owner) => {
|
|
2026
|
+
if (owner.kind === "context") return {
|
|
2027
|
+
subject: parseRepositoryPath(owner.id),
|
|
2028
|
+
entity: { contextPath: parseRepositoryPath(owner.id) }
|
|
2029
|
+
};
|
|
2030
|
+
if (owner.kind === "decision") return {
|
|
2031
|
+
subject: parseRepositoryPath(owner.id),
|
|
2032
|
+
entity: { decisionId: parseDecisionIdFromPath(parseRepositoryPath(owner.id)) ?? owner.id }
|
|
2033
|
+
};
|
|
2034
|
+
const agentId = owner.agentId ?? owner.id;
|
|
2035
|
+
return {
|
|
2036
|
+
subject: parseRepositoryPath(`/moldea/agents/${agentId}/instruction.md`),
|
|
2037
|
+
entity: {
|
|
2038
|
+
agentId,
|
|
2039
|
+
...owner.kind === "tool" || owner.kind === "skill" ? {
|
|
2040
|
+
capabilityId: owner.id,
|
|
2041
|
+
capabilityKind: owner.kind
|
|
2042
|
+
} : {}
|
|
2043
|
+
}
|
|
2044
|
+
};
|
|
2045
|
+
};
|
|
2046
|
+
/** Groups patterns by their complete fixed directory prefix to share source traversal. */
|
|
2047
|
+
var groupPatterns = (manifest) => {
|
|
2048
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2049
|
+
for (const declaration of collectManifestScopeDeclarations(manifest)) {
|
|
2050
|
+
if (declaration.field !== "affectedBy" || declaration.declaration.kind !== "glob") continue;
|
|
2051
|
+
const pattern = declaration.declaration.pattern;
|
|
2052
|
+
const segments = pattern.slice(1).split("/");
|
|
2053
|
+
const wildcard = segments.findIndex((segment) => segment.includes("*"));
|
|
2054
|
+
const prefix = parseRepositoryPath("/" + segments.slice(0, wildcard).join("/"));
|
|
2055
|
+
const group = groups.get(prefix) ?? [];
|
|
2056
|
+
group.push({
|
|
2057
|
+
declaration,
|
|
2058
|
+
pattern,
|
|
2059
|
+
segments
|
|
2060
|
+
});
|
|
2061
|
+
groups.set(prefix, group);
|
|
2062
|
+
}
|
|
2063
|
+
return groups;
|
|
2064
|
+
};
|
|
2065
|
+
/**
|
|
2066
|
+
* Checks globs only after required inspection, sharing bounded traversals and stopping on matches.
|
|
2067
|
+
* @returns Completed warnings, or no warnings when any traversal exhausts its resource budget.
|
|
2068
|
+
* @throws
|
|
2069
|
+
* - ABORTED: The Core operation was aborted.
|
|
2070
|
+
* - ABORTED: The repository operation was aborted.
|
|
2071
|
+
* - ENTRY_NOT_FOUND: The requested repository entry was not found.
|
|
2072
|
+
* - ENTRY_NOT_DIRECTORY: The requested repository entry is not a directory.
|
|
2073
|
+
* - PROVIDER_INCOMPLETE: The repository provider cannot expose a complete result.
|
|
2074
|
+
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
2075
|
+
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
2076
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
2077
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
2078
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
2079
|
+
*/
|
|
2080
|
+
var inspectImpactPatterns = async (reader, manifest, limits, signal) => {
|
|
2081
|
+
const unmatched = [];
|
|
2082
|
+
try {
|
|
2083
|
+
for (const [prefix, patterns] of groupPatterns(manifest)) {
|
|
2084
|
+
const pending = new Set(patterns);
|
|
2085
|
+
if ((await reader.getEntry(prefix, signal === void 0 ? void 0 : { signal }))?.type === "directory") for await (const candidate of reader.iterateEntries({
|
|
2086
|
+
prefix,
|
|
2087
|
+
...signal === void 0 ? {} : { signal }
|
|
2088
|
+
})) {
|
|
2089
|
+
if (candidate.type !== "file") continue;
|
|
2090
|
+
for (const pattern of pending) if (matchesRepositoryGlob(pattern.segments, candidate.path)) pending.delete(pattern);
|
|
2091
|
+
if (pending.size === 0) break;
|
|
2092
|
+
}
|
|
2093
|
+
unmatched.push(...pending);
|
|
2094
|
+
}
|
|
2095
|
+
} catch (error) {
|
|
2096
|
+
if (error instanceof CoreOperationException && error.code === "RESOURCE_LIMIT_EXCEEDED" && error.limit === "maxEntries" || error instanceof RepositorySourceException && error.code === "RESOURCE_LIMIT_EXCEEDED") return {
|
|
2097
|
+
completed: false,
|
|
2098
|
+
diagnostics: []
|
|
2099
|
+
};
|
|
2100
|
+
throw error;
|
|
2101
|
+
}
|
|
2102
|
+
const collector = createCoreDiagnosticCollector(limits, "validate-project");
|
|
2103
|
+
for (const { declaration, pattern } of unmatched) {
|
|
2104
|
+
const { subject, entity } = getOwner(declaration.owner);
|
|
2105
|
+
collector.add({
|
|
2106
|
+
code: "MOLDEA_IMPACT_PATTERN_UNMATCHED",
|
|
2107
|
+
path: parseRepositoryPath("/moldea/moldea.yaml"),
|
|
2108
|
+
pointer: declaration.pointer,
|
|
2109
|
+
subject,
|
|
2110
|
+
qualifier: pattern,
|
|
2111
|
+
entity,
|
|
2112
|
+
details: {
|
|
2113
|
+
pattern,
|
|
2114
|
+
owner: subject
|
|
2115
|
+
}
|
|
2116
|
+
});
|
|
3775
2117
|
}
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
details: {
|
|
3781
|
-
referencedPath,
|
|
3782
|
-
targetStatus: parsedDecision.status
|
|
3783
|
-
},
|
|
3784
|
-
entity: createDecisionEntity(referencedPath, agentId),
|
|
3785
|
-
path: context.manifestPath,
|
|
3786
|
-
pointer
|
|
3787
|
-
});
|
|
2118
|
+
return {
|
|
2119
|
+
completed: true,
|
|
2120
|
+
diagnostics: collector.finalize()
|
|
2121
|
+
};
|
|
3788
2122
|
};
|
|
2123
|
+
//#endregion
|
|
2124
|
+
//#region src/warning-acceptance/acceptance.ts
|
|
2125
|
+
var identity = (entry) => JSON.stringify([
|
|
2126
|
+
entry.code,
|
|
2127
|
+
entry.subject,
|
|
2128
|
+
entry.qualifier ?? null
|
|
2129
|
+
]);
|
|
3789
2130
|
/**
|
|
3790
|
-
*
|
|
3791
|
-
* @
|
|
3792
|
-
* @param manifest The normalized manifest contract to validate.
|
|
3793
|
-
* @param discovery The canonical repository discovery result.
|
|
3794
|
-
* @param decisions The successfully parsed canonical decisions.
|
|
3795
|
-
* @param limits The resource limits applied to emitted diagnostics.
|
|
3796
|
-
* @returns The frozen deterministic relationship diagnostics.
|
|
2131
|
+
* Applies explicit manifest acceptances only to checks that completed, retaining all findings.
|
|
2132
|
+
* @returns Normalized diagnostics with acceptance flags, reasons, and obsolete-acceptance warnings.
|
|
3797
2133
|
* @throws
|
|
3798
|
-
* - RESOURCE_LIMIT_EXCEEDED:
|
|
2134
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
3799
2135
|
*/
|
|
3800
|
-
var
|
|
2136
|
+
var applyWarningAcceptances = (diagnostics, entries, completed, limits) => {
|
|
2137
|
+
const acceptances = new Map(entries.map((entry, index) => [identity(entry), {
|
|
2138
|
+
entry,
|
|
2139
|
+
index
|
|
2140
|
+
}]));
|
|
2141
|
+
const matched = /* @__PURE__ */ new Set();
|
|
2142
|
+
const results = diagnostics.map((diagnostic) => {
|
|
2143
|
+
if (diagnostic.severity !== "warning" || !diagnostic.acceptable || !completed.has(diagnostic.code)) return diagnostic;
|
|
2144
|
+
const key = identity(diagnostic);
|
|
2145
|
+
const acceptance = acceptances.get(key);
|
|
2146
|
+
if (acceptance === void 0) return diagnostic;
|
|
2147
|
+
matched.add(key);
|
|
2148
|
+
return freezeRecursively({
|
|
2149
|
+
...diagnostic,
|
|
2150
|
+
accepted: true,
|
|
2151
|
+
reason: acceptance.entry.reason
|
|
2152
|
+
});
|
|
2153
|
+
});
|
|
3801
2154
|
const collector = createCoreDiagnosticCollector(limits, "validate-project");
|
|
3802
|
-
const
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
const agent = manifest.agents?.[agentId];
|
|
3818
|
-
if (agent === void 0) continue;
|
|
3819
|
-
const escapedAgentId = escapeJsonPointerSegment(agentId);
|
|
3820
|
-
for (const referencedPath of [...agent.context ?? []].sort(compareExactStrings)) validateContextRelationship(referencedPath, `/agents/${escapedAgentId}/context`, validationContext.validAgentContextPaths, validationContext, agentId);
|
|
3821
|
-
for (const referencedPath of [...agent.decisions ?? []].sort(compareExactStrings)) validateDecisionRelationship(referencedPath, `/agents/${escapedAgentId}/decisions`, validationContext, agentId);
|
|
2155
|
+
for (const [key, { entry, index }] of acceptances) {
|
|
2156
|
+
if (matched.has(key) || !completed.has(entry.code)) continue;
|
|
2157
|
+
const pointer = `/acceptedWarnings/${index}`;
|
|
2158
|
+
collector.add({
|
|
2159
|
+
code: "MOLDEA_ACCEPTANCE_UNMATCHED",
|
|
2160
|
+
path: parseRepositoryPath("/moldea/moldea.yaml"),
|
|
2161
|
+
pointer,
|
|
2162
|
+
subject: parseRepositoryPath("/moldea/moldea.yaml"),
|
|
2163
|
+
qualifier: pointer,
|
|
2164
|
+
details: {
|
|
2165
|
+
code: entry.code,
|
|
2166
|
+
subject: entry.subject,
|
|
2167
|
+
qualifier: entry.qualifier ?? null
|
|
2168
|
+
}
|
|
2169
|
+
});
|
|
3822
2170
|
}
|
|
3823
|
-
return collector.finalize();
|
|
2171
|
+
return normalizeDiagnostics([...results, ...collector.finalize()]);
|
|
3824
2172
|
};
|
|
3825
2173
|
//#endregion
|
|
3826
2174
|
//#region src/mirrors/index.ts
|
|
@@ -4057,8 +2405,56 @@ var createProjectIndex = (input) => {
|
|
|
4057
2405
|
});
|
|
4058
2406
|
};
|
|
4059
2407
|
//#endregion
|
|
2408
|
+
//#region src/export-inventory/inventory.ts
|
|
2409
|
+
/** Identifies syntax-only source formats with explicit runtime export semantics. */
|
|
2410
|
+
var isSupportedExportSource = (path) => !/\.d\.(?:ts|tsx|mts|cts)$/.test(path) && /\.(?:ts|tsx|mts|cts|js|mjs|jsx)$/.test(path);
|
|
2411
|
+
/**
|
|
2412
|
+
* Reads and parses a declared source once, retaining only its export-name set.
|
|
2413
|
+
* @returns A conclusive inventory or the precise reason analysis could not run.
|
|
2414
|
+
* @throws
|
|
2415
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
2416
|
+
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
2417
|
+
* - ABORTED: The Core operation was aborted.
|
|
2418
|
+
* - ABORTED: The repository operation was aborted.
|
|
2419
|
+
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
2420
|
+
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
2421
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
2422
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
2423
|
+
* - ENTRY_NOT_FOUND: The requested repository entry was not found.
|
|
2424
|
+
* - ENTRY_NOT_FILE: The requested repository entry is not a file.
|
|
2425
|
+
*/
|
|
2426
|
+
var readExportInventory = async (reader, path) => {
|
|
2427
|
+
if (!isSupportedExportSource(path)) return {
|
|
2428
|
+
kind: "not-checked",
|
|
2429
|
+
reason: "unsupported-file-type"
|
|
2430
|
+
};
|
|
2431
|
+
const ledger = getRetainedMemory(reader);
|
|
2432
|
+
const source = await ledger.readSourceFile(path);
|
|
2433
|
+
const reservation = 65536 + source.bytes.byteLength * 520;
|
|
2434
|
+
try {
|
|
2435
|
+
if (!ledger.tryReserve(reservation)) return {
|
|
2436
|
+
kind: "not-checked",
|
|
2437
|
+
reason: "resource-limit"
|
|
2438
|
+
};
|
|
2439
|
+
try {
|
|
2440
|
+
const { inventoryExports } = await import("./syntax-CVvExx4R.js");
|
|
2441
|
+
const result = inventoryExports(path, source.bytes);
|
|
2442
|
+
if (result.kind === "parsed") {
|
|
2443
|
+
let bytes = 64;
|
|
2444
|
+
for (const name of result.names) bytes += 64 + name.length * 2;
|
|
2445
|
+
ledger.reserve(bytes);
|
|
2446
|
+
}
|
|
2447
|
+
return result;
|
|
2448
|
+
} finally {
|
|
2449
|
+
ledger.release(reservation);
|
|
2450
|
+
}
|
|
2451
|
+
} finally {
|
|
2452
|
+
source.release();
|
|
2453
|
+
}
|
|
2454
|
+
};
|
|
2455
|
+
//#endregion
|
|
4060
2456
|
//#region src/repository-reference-validation/index.ts
|
|
4061
|
-
var childPointer
|
|
2457
|
+
var childPointer = (pointer, segment) => {
|
|
4062
2458
|
return `${pointer}/${escapeJsonPointerSegment(segment)}`;
|
|
4063
2459
|
};
|
|
4064
2460
|
var compareNullableStrings = (left, right) => {
|
|
@@ -4069,12 +2465,14 @@ var compareReferences = (left, right) => {
|
|
|
4069
2465
|
return compareExactStrings(left.path, right.path) || compareNullableStrings(left.symbol, right.symbol);
|
|
4070
2466
|
};
|
|
4071
2467
|
/** Adds sorted repository-reference array entries with their normalized indexes. */
|
|
4072
|
-
var addReferenceCandidates = (candidates, references, pointer, entity) => {
|
|
2468
|
+
var addReferenceCandidates = (candidates, references, pointer, entity, relationship) => {
|
|
4073
2469
|
for (const [index, reference] of [...references ?? []].sort(compareReferences).entries()) candidates.push({
|
|
4074
2470
|
entity,
|
|
4075
2471
|
kind: "reference",
|
|
4076
2472
|
path: reference.path,
|
|
4077
|
-
pointer: childPointer
|
|
2473
|
+
pointer: childPointer(pointer, String(index)),
|
|
2474
|
+
...relationship === void 0 ? {} : { relationship },
|
|
2475
|
+
...reference.symbol === void 0 ? {} : { symbol: reference.symbol }
|
|
4078
2476
|
});
|
|
4079
2477
|
};
|
|
4080
2478
|
/** Adds sorted exact impact paths while retaining skipped glob indexes. */
|
|
@@ -4085,26 +2483,26 @@ var addImpactCandidates = (candidates, affectedBy, pointer, entity) => {
|
|
|
4085
2483
|
entity,
|
|
4086
2484
|
kind: "impact",
|
|
4087
2485
|
path: parseRepositoryPath(pattern),
|
|
4088
|
-
pointer: childPointer
|
|
2486
|
+
pointer: childPointer(pointer, String(index))
|
|
4089
2487
|
});
|
|
4090
2488
|
}
|
|
4091
2489
|
};
|
|
4092
2490
|
/** Adds repository-backed declarations owned by one context or decision relationship. */
|
|
4093
2491
|
var addRelationshipCandidates = (candidates, relationship, pointer, entity) => {
|
|
4094
|
-
addReferenceCandidates(candidates, relationship.bindings, childPointer
|
|
4095
|
-
addImpactCandidates(candidates, relationship.affectedBy, childPointer
|
|
2492
|
+
addReferenceCandidates(candidates, relationship.bindings, childPointer(pointer, "bindings"), entity, pointer.startsWith("/context/") ? "context-binding" : "decision-binding");
|
|
2493
|
+
addImpactCandidates(candidates, relationship.affectedBy, childPointer(pointer, "affectedBy"), entity);
|
|
4096
2494
|
};
|
|
4097
2495
|
/** Adds related repository references from sorted unresolved requirements. */
|
|
4098
2496
|
var addUnresolvedCandidates = (candidates, requirements, pointer, entity) => {
|
|
4099
2497
|
for (const requirementId of Object.keys(requirements ?? {}).sort(compareExactStrings)) {
|
|
4100
2498
|
const requirement = requirements?.[requirementId];
|
|
4101
2499
|
if (requirement === void 0) continue;
|
|
4102
|
-
addReferenceCandidates(candidates, requirement.related, childPointer
|
|
2500
|
+
addReferenceCandidates(candidates, requirement.related, childPointer(childPointer(pointer, requirementId), "related"), entity);
|
|
4103
2501
|
}
|
|
4104
2502
|
};
|
|
4105
2503
|
/** Adds one capability's implementation, optional bindings, and exact impact paths. */
|
|
4106
2504
|
var addCapabilityCandidates = (candidates, capability, capabilityKind, capabilityId, agentId, collectionPointer, additionalReferences = []) => {
|
|
4107
|
-
const capabilityPointer = childPointer
|
|
2505
|
+
const capabilityPointer = childPointer(collectionPointer, capabilityId);
|
|
4108
2506
|
const capabilityEntity = {
|
|
4109
2507
|
agentId,
|
|
4110
2508
|
capabilityId,
|
|
@@ -4113,22 +2511,26 @@ var addCapabilityCandidates = (candidates, capability, capabilityKind, capabilit
|
|
|
4113
2511
|
candidates.push({
|
|
4114
2512
|
entity: capabilityEntity,
|
|
4115
2513
|
kind: `${capabilityKind}-implementation`,
|
|
2514
|
+
relationship: `${capabilityKind}-implementation`,
|
|
2515
|
+
...capability.implementation.symbol === void 0 ? {} : { symbol: capability.implementation.symbol },
|
|
4116
2516
|
path: capability.implementation.path,
|
|
4117
|
-
pointer: childPointer
|
|
2517
|
+
pointer: childPointer(capabilityPointer, "implementation")
|
|
4118
2518
|
});
|
|
4119
2519
|
for (const [property, reference] of [["registration", capability.registration], ...additionalReferences]) if (reference !== void 0) candidates.push({
|
|
4120
2520
|
entity: capabilityEntity,
|
|
4121
2521
|
kind: "reference",
|
|
4122
2522
|
path: reference.path,
|
|
4123
|
-
pointer: childPointer
|
|
2523
|
+
pointer: childPointer(capabilityPointer, property),
|
|
2524
|
+
relationship: `${capabilityKind}-${property === "inputSchema" ? "input-schema" : property === "outputSchema" ? "output-schema" : "registration"}`,
|
|
2525
|
+
...reference.symbol === void 0 ? {} : { symbol: reference.symbol }
|
|
4124
2526
|
});
|
|
4125
|
-
addImpactCandidates(candidates, capability.affectedBy, childPointer
|
|
2527
|
+
addImpactCandidates(candidates, capability.affectedBy, childPointer(capabilityPointer, "affectedBy"), capabilityEntity);
|
|
4126
2528
|
};
|
|
4127
2529
|
/** Adds all repository-backed declarations owned by one normalized agent. */
|
|
4128
2530
|
var addAgentCandidates = (candidates, agentId, agent) => {
|
|
4129
2531
|
const pointer = `/agents/${escapeJsonPointerSegment(agentId)}`;
|
|
4130
2532
|
const entity = { agentId };
|
|
4131
|
-
const bindingsPointer = childPointer
|
|
2533
|
+
const bindingsPointer = childPointer(pointer, "bindings");
|
|
4132
2534
|
const bindings = agent.bindings;
|
|
4133
2535
|
for (const property of [
|
|
4134
2536
|
"runtimeAgent",
|
|
@@ -4141,7 +2543,14 @@ var addAgentCandidates = (candidates, agentId, agent) => {
|
|
|
4141
2543
|
entity,
|
|
4142
2544
|
kind: "reference",
|
|
4143
2545
|
path: reference.path,
|
|
4144
|
-
pointer: childPointer
|
|
2546
|
+
pointer: childPointer(bindingsPointer, property),
|
|
2547
|
+
relationship: {
|
|
2548
|
+
runtimeAgent: "runtime-agent",
|
|
2549
|
+
inputSchema: "agent-input-schema",
|
|
2550
|
+
outputSchema: "agent-output-schema",
|
|
2551
|
+
instructionLoader: "instruction-loader"
|
|
2552
|
+
}[property],
|
|
2553
|
+
...reference.symbol === void 0 ? {} : { symbol: reference.symbol }
|
|
4145
2554
|
});
|
|
4146
2555
|
}
|
|
4147
2556
|
for (const variableId of Object.keys(bindings?.variableProviders ?? {}).sort(compareExactStrings)) {
|
|
@@ -4151,23 +2560,25 @@ var addAgentCandidates = (candidates, agentId, agent) => {
|
|
|
4151
2560
|
agentId,
|
|
4152
2561
|
variableId
|
|
4153
2562
|
},
|
|
2563
|
+
relationship: "variable-provider",
|
|
2564
|
+
...reference.symbol === void 0 ? {} : { symbol: reference.symbol },
|
|
4154
2565
|
kind: "reference",
|
|
4155
2566
|
path: reference.path,
|
|
4156
|
-
pointer: childPointer
|
|
2567
|
+
pointer: childPointer(childPointer(bindingsPointer, "variableProviders"), variableId)
|
|
4157
2568
|
});
|
|
4158
2569
|
}
|
|
4159
|
-
addImpactCandidates(candidates, agent.affectedBy, childPointer
|
|
4160
|
-
const toolsPointer = childPointer
|
|
2570
|
+
addImpactCandidates(candidates, agent.affectedBy, childPointer(pointer, "affectedBy"), entity);
|
|
2571
|
+
const toolsPointer = childPointer(pointer, "tools");
|
|
4161
2572
|
for (const capabilityId of Object.keys(agent.tools ?? {}).sort(compareExactStrings)) {
|
|
4162
2573
|
const capability = agent.tools?.[capabilityId];
|
|
4163
2574
|
if (capability !== void 0) addCapabilityCandidates(candidates, capability, "tool", capabilityId, agentId, toolsPointer, [["inputSchema", capability.inputSchema], ["outputSchema", capability.outputSchema]]);
|
|
4164
2575
|
}
|
|
4165
|
-
const skillsPointer = childPointer
|
|
2576
|
+
const skillsPointer = childPointer(pointer, "skills");
|
|
4166
2577
|
for (const capabilityId of Object.keys(agent.skills ?? {}).sort(compareExactStrings)) {
|
|
4167
2578
|
const capability = agent.skills?.[capabilityId];
|
|
4168
2579
|
if (capability !== void 0) addCapabilityCandidates(candidates, capability, "skill", capabilityId, agentId, skillsPointer);
|
|
4169
2580
|
}
|
|
4170
|
-
addUnresolvedCandidates(candidates, agent.unresolved, childPointer
|
|
2581
|
+
addUnresolvedCandidates(candidates, agent.unresolved, childPointer(pointer, "unresolved"), entity);
|
|
4171
2582
|
};
|
|
4172
2583
|
/** Collects every repository-backed manifest declaration in deterministic pointer order. */
|
|
4173
2584
|
var collectCandidates = (manifest) => {
|
|
@@ -4177,9 +2588,9 @@ var collectCandidates = (manifest) => {
|
|
|
4177
2588
|
for (const referencedPath of Object.keys(relationships ?? {}).sort(compareExactStrings)) {
|
|
4178
2589
|
const relationship = relationships?.[referencedPath];
|
|
4179
2590
|
if (relationship === void 0) continue;
|
|
4180
|
-
const pointer = childPointer
|
|
2591
|
+
const pointer = childPointer(`/${property}`, referencedPath);
|
|
4181
2592
|
const decisionId = property === "decisions" ? parseDecisionIdFromPath(parseRepositoryPath(referencedPath)) : null;
|
|
4182
|
-
addRelationshipCandidates(candidates, relationship, pointer, decisionId === null ?
|
|
2593
|
+
addRelationshipCandidates(candidates, relationship, pointer, decisionId === null ? { contextPath: parseRepositoryPath(referencedPath) } : { decisionId });
|
|
4183
2594
|
}
|
|
4184
2595
|
}
|
|
4185
2596
|
addUnresolvedCandidates(candidates, manifest.unresolved, "/unresolved", null);
|
|
@@ -4236,19 +2647,25 @@ var validateCandidate = (candidate, entry, manifestPath, collector) => {
|
|
|
4236
2647
|
* @param discovery Canonical discovery state used to suppress dependent path diagnostics.
|
|
4237
2648
|
* @param limits The resource limits applied to emitted diagnostics.
|
|
4238
2649
|
* @param signal Optional cancellation forwarded to exact repository lookups.
|
|
2650
|
+
* @param coverage Operation-owned binding coverage populated only for regular files.
|
|
4239
2651
|
* @returns Deeply immutable deterministic repository-reference diagnostics.
|
|
4240
2652
|
* @throws
|
|
4241
|
-
* - INVALID_REPOSITORY_PATH:
|
|
2653
|
+
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
2654
|
+
* - ENTRY_NOT_FOUND: The requested repository entry was not found.
|
|
2655
|
+
* - ENTRY_NOT_FILE: The requested repository entry is not a file.
|
|
4242
2656
|
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
4243
2657
|
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
4244
|
-
* - SNAPSHOT_CHANGED: The repository snapshot changed during
|
|
4245
|
-
* - INVALID_SOURCE_DATA: The repository
|
|
4246
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core
|
|
4247
|
-
* -
|
|
2658
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
2659
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
2660
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
2661
|
+
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
2662
|
+
* - ABORTED: The Core operation was aborted.
|
|
2663
|
+
* - ABORTED: The repository operation was aborted.
|
|
4248
2664
|
*/
|
|
4249
|
-
var validateRepositoryReferences = async (repository, manifestPath, manifest, discovery, limits, signal) => {
|
|
2665
|
+
var validateRepositoryReferences = async (repository, manifestPath, manifest, discovery, limits, signal, coverage = []) => {
|
|
4250
2666
|
const collector = createCoreDiagnosticCollector(limits, "validate-project");
|
|
4251
2667
|
const blockedPaths = new Set(discovery.diagnostics.flatMap((diagnostic) => diagnostic.path === null ? [] : [diagnostic.path]));
|
|
2668
|
+
const inventories = /* @__PURE__ */ new Map();
|
|
4252
2669
|
const entryCache = /* @__PURE__ */ new Map();
|
|
4253
2670
|
const operationOptions = signal === void 0 ? void 0 : { signal };
|
|
4254
2671
|
for (const candidate of collectCandidates(manifest)) {
|
|
@@ -4258,7 +2675,70 @@ var validateRepositoryReferences = async (repository, manifestPath, manifest, di
|
|
|
4258
2675
|
entryPromise = repository.getEntry(candidate.path, operationOptions);
|
|
4259
2676
|
entryCache.set(candidate.path, entryPromise);
|
|
4260
2677
|
}
|
|
4261
|
-
|
|
2678
|
+
const entry = await entryPromise;
|
|
2679
|
+
validateCandidate(candidate, entry, manifestPath, collector);
|
|
2680
|
+
if (entry?.type !== "file" || candidate.relationship === void 0) continue;
|
|
2681
|
+
if (coverage.length >= limits.maxCoverage) throw new CoreOperationException({
|
|
2682
|
+
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
2683
|
+
operation: "validate-project",
|
|
2684
|
+
limit: "maxCoverage",
|
|
2685
|
+
limitMaximum: limits.maxCoverage,
|
|
2686
|
+
observedUsage: coverage.length + 1,
|
|
2687
|
+
nextAction: "reduce-input-or-increase-limit"
|
|
2688
|
+
});
|
|
2689
|
+
const base = {
|
|
2690
|
+
entity: candidate.entity ?? {},
|
|
2691
|
+
relationship: candidate.relationship,
|
|
2692
|
+
path: candidate.path,
|
|
2693
|
+
symbol: candidate.symbol ?? null,
|
|
2694
|
+
fileCheck: "passed"
|
|
2695
|
+
};
|
|
2696
|
+
let record;
|
|
2697
|
+
if (candidate.symbol === void 0) record = {
|
|
2698
|
+
...base,
|
|
2699
|
+
exportCheck: "not-checked",
|
|
2700
|
+
exportNotCheckedReason: "no-symbol"
|
|
2701
|
+
};
|
|
2702
|
+
else {
|
|
2703
|
+
let inventory = inventories.get(candidate.path);
|
|
2704
|
+
if (inventory === void 0) {
|
|
2705
|
+
inventory = await readExportInventory(repository, candidate.path);
|
|
2706
|
+
inventories.set(candidate.path, inventory);
|
|
2707
|
+
}
|
|
2708
|
+
if (inventory.kind === "not-checked") record = {
|
|
2709
|
+
...base,
|
|
2710
|
+
exportCheck: "not-checked",
|
|
2711
|
+
exportNotCheckedReason: inventory.reason
|
|
2712
|
+
};
|
|
2713
|
+
else if (!inventory.complete) record = {
|
|
2714
|
+
...base,
|
|
2715
|
+
exportCheck: "not-checked",
|
|
2716
|
+
exportNotCheckedReason: "unresolved-exports"
|
|
2717
|
+
};
|
|
2718
|
+
else if (inventory.names.has(candidate.symbol)) record = {
|
|
2719
|
+
...base,
|
|
2720
|
+
exportCheck: "passed"
|
|
2721
|
+
};
|
|
2722
|
+
else {
|
|
2723
|
+
record = {
|
|
2724
|
+
...base,
|
|
2725
|
+
exportCheck: "failed"
|
|
2726
|
+
};
|
|
2727
|
+
collector.add({
|
|
2728
|
+
code: "MOLDEA_REFERENCE_EXPORT_MISSING",
|
|
2729
|
+
entity: candidate.entity,
|
|
2730
|
+
path: manifestPath,
|
|
2731
|
+
pointer: candidate.pointer,
|
|
2732
|
+
details: {
|
|
2733
|
+
referencedPath: candidate.path,
|
|
2734
|
+
symbol: candidate.symbol,
|
|
2735
|
+
relationship: candidate.relationship
|
|
2736
|
+
}
|
|
2737
|
+
});
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
reserveRetainedBytesIfTracked(repository, 512 + JSON.stringify(record).length * 2);
|
|
2741
|
+
coverage.push(record);
|
|
4262
2742
|
}
|
|
4263
2743
|
return collector.finalize();
|
|
4264
2744
|
};
|
|
@@ -4342,25 +2822,28 @@ var addDiagnostics = (collector, diagnostics) => {
|
|
|
4342
2822
|
for (const diagnostic of diagnostics) collector.merge(diagnostic);
|
|
4343
2823
|
};
|
|
4344
2824
|
/**
|
|
4345
|
-
* Executes every universal repository-format phase
|
|
2825
|
+
* Executes every universal repository-format phase with syntax-only export checks.
|
|
4346
2826
|
* @param context The shared inspection session and optional cancellation signal.
|
|
4347
2827
|
* @param options The immutable Core configuration snapshot.
|
|
4348
2828
|
* @returns The frozen provisional index only when no universal diagnostic remains.
|
|
4349
2829
|
* @throws
|
|
4350
|
-
* - INVALID_REPOSITORY_PATH:
|
|
4351
|
-
* - ENTRY_NOT_FOUND:
|
|
4352
|
-
* - ENTRY_NOT_FILE:
|
|
4353
|
-
* - ENTRY_NOT_DIRECTORY:
|
|
2830
|
+
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
2831
|
+
* - ENTRY_NOT_FOUND: The requested repository entry was not found.
|
|
2832
|
+
* - ENTRY_NOT_FILE: The requested repository entry is not a file.
|
|
2833
|
+
* - ENTRY_NOT_DIRECTORY: The requested repository entry is not a directory.
|
|
4354
2834
|
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
4355
2835
|
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
4356
|
-
* - SNAPSHOT_CHANGED: The repository snapshot changed during
|
|
4357
|
-
* - INVALID_SOURCE_DATA: The repository
|
|
4358
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core
|
|
4359
|
-
* -
|
|
2836
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
2837
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
2838
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
2839
|
+
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
2840
|
+
* - ABORTED: The Core operation was aborted.
|
|
2841
|
+
* - ABORTED: The repository operation was aborted.
|
|
4360
2842
|
*/
|
|
4361
2843
|
var inspectUniversalProject = async (context, options) => {
|
|
4362
2844
|
options = createCoreOperationOptionsSnapshot(options);
|
|
4363
2845
|
const { session, signal } = context;
|
|
2846
|
+
const coverage = [];
|
|
4364
2847
|
const collector = createCoreDiagnosticCollector(options.limits, "validate-project");
|
|
4365
2848
|
const operationOptions = signal === void 0 ? void 0 : { signal };
|
|
4366
2849
|
const moldeaRoot = await session.reader.getEntry(MOLDEA_ROOT, operationOptions);
|
|
@@ -4368,16 +2851,15 @@ var inspectUniversalProject = async (context, options) => {
|
|
|
4368
2851
|
let projectEntry = null;
|
|
4369
2852
|
let indexedManifest = null;
|
|
4370
2853
|
let formatVersion = null;
|
|
4371
|
-
let runtimeLocations = [];
|
|
4372
2854
|
if (moldeaRoot?.type === "directory") {
|
|
4373
2855
|
manifestEntry = await session.reader.getEntry(MANIFEST_PATH, operationOptions);
|
|
4374
2856
|
if (manifestEntry?.type === "file") {
|
|
2857
|
+
const content = await session.reader.readCompleteFile(MANIFEST_PATH, operationOptions);
|
|
4375
2858
|
const parsedManifest = await inspectManifestDocument({
|
|
4376
|
-
content
|
|
2859
|
+
content,
|
|
4377
2860
|
path: MANIFEST_PATH
|
|
4378
2861
|
}, options, "validate-project");
|
|
4379
2862
|
formatVersion = parsedManifest.formatVersion;
|
|
4380
|
-
runtimeLocations = parsedManifest.runtimeLocations;
|
|
4381
2863
|
addDiagnostics(collector, parsedManifest.diagnostics);
|
|
4382
2864
|
if (parsedManifest.asset !== null && parsedManifest.manifest !== null) indexedManifest = {
|
|
4383
2865
|
asset: parsedManifest.asset,
|
|
@@ -4409,14 +2891,25 @@ var inspectUniversalProject = async (context, options) => {
|
|
|
4409
2891
|
agents = agentAssets.agents;
|
|
4410
2892
|
addDiagnostics(collector, agentAssets.diagnostics);
|
|
4411
2893
|
addDiagnostics(collector, validateManifestRelationships(manifestPath, indexedManifest.value, discovery, decisionGraph.decisions, options.limits));
|
|
4412
|
-
addDiagnostics(collector, await validateRepositoryReferences(session.reader, manifestPath, indexedManifest.value, discovery, options.limits, signal));
|
|
2894
|
+
addDiagnostics(collector, await validateRepositoryReferences(session.reader, manifestPath, indexedManifest.value, discovery, options.limits, signal, coverage));
|
|
4413
2895
|
const mirrorInspection = await inspectMirrors(session.reader, manifestPath, agents, options, signal);
|
|
4414
2896
|
agentMirrors = mirrorInspection.agentMirrors;
|
|
4415
2897
|
addDiagnostics(collector, mirrorInspection.diagnostics);
|
|
4416
2898
|
}
|
|
4417
2899
|
session.throwIfAborted();
|
|
4418
|
-
|
|
4419
|
-
const
|
|
2900
|
+
addDiagnostics(collector, await inspectCodingAgentIntegration(session.reader, options.limits, signal));
|
|
2901
|
+
const patterns = indexedManifest === null ? {
|
|
2902
|
+
completed: false,
|
|
2903
|
+
diagnostics: []
|
|
2904
|
+
} : await inspectImpactPatterns(session.reader, indexedManifest.value, options.limits, signal);
|
|
2905
|
+
session.throwIfAborted();
|
|
2906
|
+
addDiagnostics(collector, patterns.diagnostics);
|
|
2907
|
+
const diagnostics = applyWarningAcceptances(collector.finalize(), indexedManifest?.value.acceptedWarnings ?? [], /* @__PURE__ */ new Set([...[
|
|
2908
|
+
"MOLDEA_INTEGRATION_BLOCK_MISSING",
|
|
2909
|
+
"MOLDEA_INTEGRATION_SKILL_MISSING",
|
|
2910
|
+
"MOLDEA_INTEGRATION_BLOCK_STALE"
|
|
2911
|
+
], ...patterns.completed ? ["MOLDEA_IMPACT_PATTERN_UNMATCHED"] : []]), options.limits);
|
|
2912
|
+
const project = !diagnostics.some((diagnostic) => diagnostic.severity === "error") && indexedManifest !== null && projectAssets.project !== null ? createProjectIndex({
|
|
4420
2913
|
agentMirrors,
|
|
4421
2914
|
agents,
|
|
4422
2915
|
context: projectAssets.context,
|
|
@@ -4427,45 +2920,45 @@ var inspectUniversalProject = async (context, options) => {
|
|
|
4427
2920
|
}) : null;
|
|
4428
2921
|
return freezeRecursively({
|
|
4429
2922
|
diagnostics,
|
|
2923
|
+
coverage,
|
|
4430
2924
|
formatVersion,
|
|
4431
|
-
project
|
|
4432
|
-
runtimeLocations
|
|
2925
|
+
project
|
|
4433
2926
|
});
|
|
4434
2927
|
};
|
|
4435
2928
|
//#endregion
|
|
4436
2929
|
//#region src/project-validation/index.ts
|
|
4437
|
-
var isRecord
|
|
2930
|
+
var isRecord = (candidate) => {
|
|
4438
2931
|
return typeof candidate === "object" && candidate !== null && !Array.isArray(candidate);
|
|
4439
2932
|
};
|
|
4440
|
-
var invalidArgument$
|
|
2933
|
+
var invalidArgument$1 = () => {
|
|
4441
2934
|
throw new CoreOperationException({
|
|
4442
2935
|
code: "INVALID_ARGUMENT",
|
|
4443
2936
|
operation: "validate-project"
|
|
4444
2937
|
});
|
|
4445
2938
|
};
|
|
4446
2939
|
var isRepositoryReader = (candidate) => {
|
|
4447
|
-
return isRecord
|
|
2940
|
+
return isRecord(candidate) && isRecord(candidate["snapshot"]) && typeof candidate["snapshot"]["id"] === "string" && typeof candidate["snapshot"]["sourceKind"] === "string" && typeof candidate["compare"] === "function" && typeof candidate["getEntry"] === "function" && typeof candidate["listEntriesPage"] === "function" && typeof candidate["readFilePage"] === "function";
|
|
4448
2941
|
};
|
|
4449
2942
|
var isAbortSignal = (candidate) => {
|
|
4450
|
-
return isRecord
|
|
2943
|
+
return isRecord(candidate) && typeof candidate["aborted"] === "boolean" && typeof candidate["addEventListener"] === "function" && typeof candidate["removeEventListener"] === "function";
|
|
4451
2944
|
};
|
|
4452
2945
|
var validateInput = (candidate) => {
|
|
4453
2946
|
try {
|
|
4454
|
-
if (!isRecord
|
|
2947
|
+
if (!isRecord(candidate)) return invalidArgument$1();
|
|
4455
2948
|
const repository = candidate["repository"];
|
|
4456
2949
|
const signal = candidate["signal"];
|
|
4457
|
-
if (Reflect.ownKeys(candidate).some((key) => key !== "repository" && key !== "signal") || !isRepositoryReader(repository) || signal !== void 0 && !isAbortSignal(signal)) return invalidArgument$
|
|
2950
|
+
if (Reflect.ownKeys(candidate).some((key) => key !== "repository" && key !== "signal") || !isRepositoryReader(repository) || signal !== void 0 && !isAbortSignal(signal)) return invalidArgument$1();
|
|
4458
2951
|
return {
|
|
4459
2952
|
repository,
|
|
4460
2953
|
...signal === void 0 ? {} : { signal }
|
|
4461
2954
|
};
|
|
4462
2955
|
} catch (error) {
|
|
4463
2956
|
if (error instanceof CoreOperationException) throw error;
|
|
4464
|
-
return invalidArgument$
|
|
2957
|
+
return invalidArgument$1();
|
|
4465
2958
|
}
|
|
4466
2959
|
};
|
|
4467
2960
|
/**
|
|
4468
|
-
* Inspects one coherent repository snapshot through universal and
|
|
2961
|
+
* Inspects one coherent repository snapshot through universal file and export validation.
|
|
4469
2962
|
* @param input The untrusted source-neutral reader and optional cancellation signal.
|
|
4470
2963
|
* @param options The immutable Core configuration snapshot.
|
|
4471
2964
|
* @returns A promise resolving to the frozen all-or-nothing project inspection result.
|
|
@@ -4484,7 +2977,6 @@ var validateInput = (candidate) => {
|
|
|
4484
2977
|
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
4485
2978
|
* - ABORTED: The repository operation was aborted.
|
|
4486
2979
|
* - ABORTED: The Core operation was aborted.
|
|
4487
|
-
* - ADAPTER_EXECUTION_FAILED: A runtime adapter failed during inspection.
|
|
4488
2980
|
*/
|
|
4489
2981
|
var validateProjectState = async (input, options) => {
|
|
4490
2982
|
const validatedInput = validateInput(input);
|
|
@@ -4494,64 +2986,27 @@ var validateProjectState = async (input, options) => {
|
|
|
4494
2986
|
session,
|
|
4495
2987
|
...validatedInput.signal === void 0 ? {} : { signal: validatedInput.signal }
|
|
4496
2988
|
}, operationOptions);
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
return freezeRecursively({
|
|
4500
|
-
project: null,
|
|
4501
|
-
resourceUsage: session.getResourceUsage(),
|
|
4502
|
-
result: {
|
|
4503
|
-
diagnostics: universal.diagnostics,
|
|
4504
|
-
...counts,
|
|
4505
|
-
evidence: [],
|
|
4506
|
-
formatVersion: universal.formatVersion,
|
|
4507
|
-
runtimeInspection: "not-run",
|
|
4508
|
-
source: validatedInput.repository.snapshot,
|
|
4509
|
-
summary: null,
|
|
4510
|
-
valid: false
|
|
4511
|
-
}
|
|
4512
|
-
});
|
|
4513
|
-
}
|
|
4514
|
-
const projectSummary = createProjectSummary(universal.project);
|
|
4515
|
-
const availabilityDiagnostics = validateRuntimeAdapterAvailability(universal.runtimeLocations, universal.project.formatVersion, operationOptions);
|
|
4516
|
-
if (availabilityDiagnostics.length > 0) {
|
|
4517
|
-
const counts = countDiagnosticsBySeverity(availabilityDiagnostics);
|
|
4518
|
-
return freezeRecursively({
|
|
4519
|
-
project: universal.project,
|
|
4520
|
-
resourceUsage: session.getResourceUsage(),
|
|
4521
|
-
result: {
|
|
4522
|
-
diagnostics: availabilityDiagnostics,
|
|
4523
|
-
...counts,
|
|
4524
|
-
evidence: [],
|
|
4525
|
-
formatVersion: universal.formatVersion,
|
|
4526
|
-
runtimeInspection: "not-run",
|
|
4527
|
-
source: validatedInput.repository.snapshot,
|
|
4528
|
-
summary: projectSummary,
|
|
4529
|
-
valid: false
|
|
4530
|
-
}
|
|
4531
|
-
});
|
|
4532
|
-
}
|
|
4533
|
-
const adapterInspection = await inspectRuntimeAdapters(universal.project, session, operationOptions, validatedInput.signal);
|
|
4534
|
-
const counts = countDiagnosticsBySeverity(adapterInspection.diagnostics);
|
|
4535
|
-
const valid = counts.errorCount === 0;
|
|
2989
|
+
session.throwIfAborted();
|
|
2990
|
+
const counts = countDiagnosticsBySeverity(universal.diagnostics);
|
|
4536
2991
|
return freezeRecursively({
|
|
4537
2992
|
project: universal.project,
|
|
4538
2993
|
resourceUsage: session.getResourceUsage(),
|
|
4539
2994
|
result: {
|
|
4540
|
-
diagnostics:
|
|
2995
|
+
diagnostics: universal.diagnostics,
|
|
4541
2996
|
...counts,
|
|
4542
|
-
|
|
2997
|
+
coverage: universal.coverage,
|
|
2998
|
+
coverageCounts: countBindingCoverage(universal.coverage),
|
|
4543
2999
|
formatVersion: universal.formatVersion,
|
|
4544
|
-
runtimeInspection: counts.warningCount === 0 ? "complete" : "incomplete",
|
|
4545
3000
|
source: validatedInput.repository.snapshot,
|
|
4546
|
-
summary:
|
|
4547
|
-
valid
|
|
3001
|
+
summary: universal.project === null ? null : createProjectSummary(universal.project),
|
|
3002
|
+
valid: counts.errorCount === 0
|
|
4548
3003
|
}
|
|
4549
3004
|
});
|
|
4550
3005
|
};
|
|
4551
3006
|
/**
|
|
4552
3007
|
* Validates one project without returning canonical document bodies.
|
|
4553
3008
|
* @param input The source-neutral reader and optional cancellation signal.
|
|
4554
|
-
* @param options The immutable
|
|
3009
|
+
* @param options The immutable operation limits.
|
|
4555
3010
|
* @returns A promise resolving to the complete validation result.
|
|
4556
3011
|
* @throws
|
|
4557
3012
|
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
@@ -4568,24 +3023,23 @@ var validateProjectState = async (input, options) => {
|
|
|
4568
3023
|
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
4569
3024
|
* - ABORTED: The repository operation was aborted.
|
|
4570
3025
|
* - ABORTED: The Core operation was aborted.
|
|
4571
|
-
* - ADAPTER_EXECUTION_FAILED: A runtime adapter failed during inspection.
|
|
4572
3026
|
*/
|
|
4573
3027
|
var validateProject = async (input, options) => (await validateProjectState(input, options)).result;
|
|
4574
3028
|
//#endregion
|
|
4575
3029
|
//#region src/project-inspection/index.ts
|
|
4576
|
-
var CURSOR_PREFIX = "
|
|
3030
|
+
var CURSOR_PREFIX = "core7";
|
|
4577
3031
|
var PREPARED_FIXED_BYTES = 512;
|
|
4578
3032
|
var PREPARED_ITEM_FIXED_BYTES = 64;
|
|
4579
3033
|
var PREPARED_TEXT_BYTE_MULTIPLIER = 2;
|
|
4580
3034
|
var PREPARED_VIEW_REFERENCE_BYTES = 8;
|
|
4581
3035
|
var encoder = new TextEncoder();
|
|
4582
|
-
var invalidArgument
|
|
3036
|
+
var invalidArgument = () => {
|
|
4583
3037
|
throw new CoreOperationException({
|
|
4584
3038
|
code: "INVALID_ARGUMENT",
|
|
4585
3039
|
operation: "create-project-inspection"
|
|
4586
3040
|
});
|
|
4587
3041
|
};
|
|
4588
|
-
var resourceLimitExceeded
|
|
3042
|
+
var resourceLimitExceeded = (limitMaximum, observedUsage) => {
|
|
4589
3043
|
throw new CoreOperationException({
|
|
4590
3044
|
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
4591
3045
|
limit: "maxRetainedBytes",
|
|
@@ -4630,10 +3084,10 @@ var createItemBaseKey = (item) => {
|
|
|
4630
3084
|
].join(":");
|
|
4631
3085
|
return [
|
|
4632
3086
|
"2",
|
|
4633
|
-
item.
|
|
4634
|
-
item.
|
|
4635
|
-
item.
|
|
4636
|
-
createIdentity([serializeDeterministically(item.
|
|
3087
|
+
item.coverage.path,
|
|
3088
|
+
item.coverage.relationship,
|
|
3089
|
+
item.coverage.entity.agentId ?? "",
|
|
3090
|
+
createIdentity([serializeDeterministically(item.coverage)])
|
|
4637
3091
|
].join(":");
|
|
4638
3092
|
};
|
|
4639
3093
|
/** Assigns stable unique keys once without relying on collection offsets. */
|
|
@@ -4667,26 +3121,26 @@ var encodeCursor = (inspectionDigest, view, lastKey) => [
|
|
|
4667
3121
|
].join(":");
|
|
4668
3122
|
var decodeCursor = (cursor, inspectionDigest, view) => {
|
|
4669
3123
|
if (cursor === void 0) return null;
|
|
4670
|
-
const match = /^
|
|
4671
|
-
if (match === null || match[1] !== view || match[3] !== inspectionDigest) return invalidArgument
|
|
3124
|
+
const match = /^core7:(all|diagnostics|coverage|metadata):([^:]+):(sha256:[0-9a-f]{64}):(sha256:[0-9a-f]{64})$/u.exec(cursor);
|
|
3125
|
+
if (match === null || match[1] !== view || match[3] !== inspectionDigest) return invalidArgument();
|
|
4672
3126
|
let lastKey;
|
|
4673
3127
|
try {
|
|
4674
3128
|
lastKey = decodeURIComponent(match[2]);
|
|
4675
3129
|
} catch {
|
|
4676
|
-
return invalidArgument
|
|
3130
|
+
return invalidArgument();
|
|
4677
3131
|
}
|
|
4678
|
-
if (lastKey.length === 0 || match[4] !== createCursorChecksum(inspectionDigest, lastKey, view)) return invalidArgument
|
|
3132
|
+
if (lastKey.length === 0 || match[4] !== createCursorChecksum(inspectionDigest, lastKey, view)) return invalidArgument();
|
|
4679
3133
|
return lastKey;
|
|
4680
3134
|
};
|
|
4681
3135
|
var createViews = (items) => freezeRecursively({
|
|
4682
3136
|
all: items,
|
|
4683
3137
|
diagnostics: items.filter(({ item }) => item.kind === "diagnostic"),
|
|
4684
|
-
|
|
3138
|
+
coverage: items.filter(({ item }) => item.kind === "coverage"),
|
|
4685
3139
|
metadata: items.filter(({ item }) => item.kind === "metadata" || item.kind === "agent")
|
|
4686
3140
|
});
|
|
4687
3141
|
var addRetainedBytes = (current, additional, retainedBeforePreparation, maximum) => {
|
|
4688
3142
|
const projectedUsage = retainedBeforePreparation + current + additional;
|
|
4689
|
-
if (!Number.isSafeInteger(additional) || additional < 0 || !Number.isSafeInteger(projectedUsage) || projectedUsage > maximum) return resourceLimitExceeded
|
|
3143
|
+
if (!Number.isSafeInteger(additional) || additional < 0 || !Number.isSafeInteger(projectedUsage) || projectedUsage > maximum) return resourceLimitExceeded(maximum, Number.isSafeInteger(projectedUsage) ? projectedUsage : Number.MAX_SAFE_INTEGER);
|
|
4690
3144
|
return current + additional;
|
|
4691
3145
|
};
|
|
4692
3146
|
/** Iterates every content-free inspection item without retaining preparation state. */
|
|
@@ -4699,9 +3153,9 @@ var iterateProjectInspectionItems = function* (state) {
|
|
|
4699
3153
|
diagnostic,
|
|
4700
3154
|
kind: "diagnostic"
|
|
4701
3155
|
};
|
|
4702
|
-
for (const
|
|
4703
|
-
|
|
4704
|
-
kind: "
|
|
3156
|
+
for (const coverage of state.result.coverage) yield {
|
|
3157
|
+
coverage,
|
|
3158
|
+
kind: "coverage"
|
|
4705
3159
|
};
|
|
4706
3160
|
if (state.project !== null) for (const agent of iterateProjectAgentAssignments(state.project)) yield {
|
|
4707
3161
|
agent,
|
|
@@ -4725,17 +3179,17 @@ var estimatePreparedProjectInspection = (state, baseCounts, maximum) => {
|
|
|
4725
3179
|
decisions: baseCounts.decisions,
|
|
4726
3180
|
diagnostics: baseCounts.diagnostics,
|
|
4727
3181
|
errors: baseCounts.errors,
|
|
4728
|
-
|
|
3182
|
+
coverage: baseCounts.coverage,
|
|
4729
3183
|
metadata: metadataCount,
|
|
4730
3184
|
mirrors: baseCounts.mirrors,
|
|
4731
3185
|
runtimes: baseCounts.runtimes,
|
|
4732
3186
|
unresolved: baseCounts.unresolved,
|
|
4733
|
-
warnings: baseCounts.warnings
|
|
3187
|
+
warnings: baseCounts.warnings,
|
|
3188
|
+
acceptedWarnings: baseCounts.acceptedWarnings
|
|
4734
3189
|
};
|
|
4735
3190
|
bytes = addRetainedBytes(bytes, encoder.encode(serializeDeterministically({
|
|
4736
3191
|
counts,
|
|
4737
3192
|
formatVersion: state.result.formatVersion,
|
|
4738
|
-
runtimeInspection: state.result.runtimeInspection,
|
|
4739
3193
|
inspectionDigest: "sha256:0000000000000000000000000000000000000000000000000000000000000000",
|
|
4740
3194
|
source: state.result.source,
|
|
4741
3195
|
summary: state.result.summary,
|
|
@@ -4747,12 +3201,12 @@ var estimatePreparedProjectInspection = (state, baseCounts, maximum) => {
|
|
|
4747
3201
|
};
|
|
4748
3202
|
};
|
|
4749
3203
|
/** Creates the inspection digest without materializing a project-sized key projection. */
|
|
4750
|
-
var createInspectionDigest = (counts, formatVersion, items, summary,
|
|
4751
|
-
yield "
|
|
3204
|
+
var createInspectionDigest = (counts, coverageCounts, formatVersion, items, summary, valid) => createIdentity((function* () {
|
|
3205
|
+
yield "core7-prepared-inspection";
|
|
4752
3206
|
yield serializeDeterministically({
|
|
4753
3207
|
counts,
|
|
3208
|
+
coverageCounts,
|
|
4754
3209
|
formatVersion,
|
|
4755
|
-
runtimeInspection,
|
|
4756
3210
|
summary,
|
|
4757
3211
|
valid
|
|
4758
3212
|
});
|
|
@@ -4765,18 +3219,18 @@ var findStartIndex = (items, lastKey) => {
|
|
|
4765
3219
|
while (lower <= upper) {
|
|
4766
3220
|
const middle = lower + Math.floor((upper - lower) / 2);
|
|
4767
3221
|
const candidate = items[middle];
|
|
4768
|
-
if (candidate === void 0) return invalidArgument
|
|
3222
|
+
if (candidate === void 0) return invalidArgument();
|
|
4769
3223
|
if (candidate.key === lastKey) return middle + 1;
|
|
4770
3224
|
if (candidate.key < lastKey) lower = middle + 1;
|
|
4771
3225
|
else upper = middle - 1;
|
|
4772
3226
|
}
|
|
4773
|
-
return invalidArgument
|
|
3227
|
+
return invalidArgument();
|
|
4774
3228
|
};
|
|
4775
3229
|
/** Creates the returned inspection from content-free state only. */
|
|
4776
3230
|
var createPreparedProjectInspection = (input) => {
|
|
4777
|
-
const { counts,
|
|
3231
|
+
const { counts, coverageCounts, formatVersion, items, maxEntries, preparedBytes, resourceUsage: validationUsage, source, summary, valid } = input;
|
|
4778
3232
|
const views = createViews(items);
|
|
4779
|
-
const inspectionDigest = createInspectionDigest(counts, formatVersion, items, summary,
|
|
3233
|
+
const inspectionDigest = createInspectionDigest(counts, coverageCounts, formatVersion, items, summary, valid);
|
|
4780
3234
|
const resourceUsage = freezeRecursively({
|
|
4781
3235
|
canonicalBytes: validationUsage.canonicalBytes,
|
|
4782
3236
|
peakRetainedBytes: Math.max(validationUsage.peakRetainedBytes, validationUsage.retainedBytes + preparedBytes),
|
|
@@ -4785,7 +3239,7 @@ var createPreparedProjectInspection = (input) => {
|
|
|
4785
3239
|
totalBytesRead: validationUsage.totalBytesRead
|
|
4786
3240
|
});
|
|
4787
3241
|
const readPage = (pageInput) => {
|
|
4788
|
-
if (typeof pageInput !== "object" || pageInput === null || Reflect.ownKeys(pageInput).some((key) => key !== "cursor" && key !== "maxItems" && key !== "view") || !Number.isSafeInteger(pageInput.maxItems) || pageInput.maxItems < 1 || pageInput.maxItems > maxEntries || pageInput.cursor !== void 0 && typeof pageInput.cursor !== "string" || pageInput.view !== "all" && pageInput.view !== "diagnostics" && pageInput.view !== "
|
|
3242
|
+
if (typeof pageInput !== "object" || pageInput === null || Reflect.ownKeys(pageInput).some((key) => key !== "cursor" && key !== "maxItems" && key !== "view") || !Number.isSafeInteger(pageInput.maxItems) || pageInput.maxItems < 1 || pageInput.maxItems > maxEntries || pageInput.cursor !== void 0 && typeof pageInput.cursor !== "string" || pageInput.view !== "all" && pageInput.view !== "diagnostics" && pageInput.view !== "coverage" && pageInput.view !== "metadata") return invalidArgument();
|
|
4789
3243
|
const viewItems = views[pageInput.view];
|
|
4790
3244
|
const startIndex = findStartIndex(viewItems, decodeCursor(pageInput.cursor, inspectionDigest, pageInput.view));
|
|
4791
3245
|
const records = viewItems.slice(startIndex, startIndex + pageInput.maxItems).map(({ item, key }, index) => {
|
|
@@ -4797,8 +3251,8 @@ var createPreparedProjectInspection = (input) => {
|
|
|
4797
3251
|
const nextCursor = records.at(-1)?.nextCursor ?? null;
|
|
4798
3252
|
return freezeRecursively({
|
|
4799
3253
|
counts,
|
|
3254
|
+
coverageCounts,
|
|
4800
3255
|
formatVersion,
|
|
4801
|
-
runtimeInspection,
|
|
4802
3256
|
inspectionDigest,
|
|
4803
3257
|
page: {
|
|
4804
3258
|
isComplete: nextCursor === null,
|
|
@@ -4814,8 +3268,8 @@ var createPreparedProjectInspection = (input) => {
|
|
|
4814
3268
|
};
|
|
4815
3269
|
return freezeRecursively({
|
|
4816
3270
|
counts,
|
|
3271
|
+
coverageCounts,
|
|
4817
3272
|
formatVersion,
|
|
4818
|
-
runtimeInspection,
|
|
4819
3273
|
inspectionDigest,
|
|
4820
3274
|
readPage,
|
|
4821
3275
|
resourceUsage,
|
|
@@ -4827,7 +3281,7 @@ var createPreparedProjectInspection = (input) => {
|
|
|
4827
3281
|
/**
|
|
4828
3282
|
* Prepares one immutable content-free inspection for synchronous bounded page reads.
|
|
4829
3283
|
* @param input The source-neutral reader and optional cancellation signal.
|
|
4830
|
-
* @param options The immutable
|
|
3284
|
+
* @param options The immutable operation limits.
|
|
4831
3285
|
* @returns A promise resolving to the complete prepared inspection.
|
|
4832
3286
|
* @throws
|
|
4833
3287
|
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
@@ -4844,7 +3298,6 @@ var createPreparedProjectInspection = (input) => {
|
|
|
4844
3298
|
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
4845
3299
|
* - ABORTED: The repository operation was aborted.
|
|
4846
3300
|
* - ABORTED: The Core operation was aborted.
|
|
4847
|
-
* - ADAPTER_EXECUTION_FAILED: A runtime adapter failed during inspection.
|
|
4848
3301
|
*/
|
|
4849
3302
|
var createProjectInspection = async (input, options) => {
|
|
4850
3303
|
const state = await validateProjectState(input, options);
|
|
@@ -4854,18 +3307,19 @@ var createProjectInspection = async (input, options) => {
|
|
|
4854
3307
|
decisions: state.result.summary?.counts.decisions ?? 0,
|
|
4855
3308
|
diagnostics: state.result.diagnostics.length,
|
|
4856
3309
|
errors: state.result.errorCount,
|
|
4857
|
-
|
|
3310
|
+
coverage: state.result.coverage.length,
|
|
4858
3311
|
mirrors: state.result.summary?.counts.mirrors ?? 0,
|
|
4859
3312
|
runtimes: state.result.summary?.counts.runtimes ?? 0,
|
|
4860
3313
|
unresolved: state.result.summary?.counts.unresolved ?? 0,
|
|
4861
|
-
warnings: state.result.warningCount
|
|
3314
|
+
warnings: state.result.warningCount,
|
|
3315
|
+
acceptedWarnings: state.result.acceptedWarningCount
|
|
4862
3316
|
}, options.limits.maxRetainedBytes);
|
|
4863
3317
|
const counts = freezeRecursively(estimate.counts);
|
|
4864
3318
|
const items = freezeRecursively(createKeyedItems(iterateProjectInspectionItems(state)));
|
|
4865
3319
|
return createPreparedProjectInspection({
|
|
4866
3320
|
counts,
|
|
3321
|
+
coverageCounts: state.result.coverageCounts,
|
|
4867
3322
|
formatVersion: state.result.formatVersion,
|
|
4868
|
-
runtimeInspection: state.result.runtimeInspection,
|
|
4869
3323
|
items,
|
|
4870
3324
|
maxEntries: options.limits.maxEntries,
|
|
4871
3325
|
preparedBytes: estimate.preparedBytes,
|
|
@@ -4876,423 +3330,28 @@ var createProjectInspection = async (input, options) => {
|
|
|
4876
3330
|
});
|
|
4877
3331
|
};
|
|
4878
3332
|
//#endregion
|
|
4879
|
-
//#region src/scope-matching/validations.ts
|
|
4880
|
-
var isRecord = (value) => {
|
|
4881
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4882
|
-
};
|
|
4883
|
-
/** Throws the stable invalid-argument failure for malformed scope input. */
|
|
4884
|
-
var invalidArgument = () => {
|
|
4885
|
-
throw new CoreOperationException({
|
|
4886
|
-
code: "INVALID_ARGUMENT",
|
|
4887
|
-
operation: "match-manifest-scope"
|
|
4888
|
-
});
|
|
4889
|
-
};
|
|
4890
|
-
/** Throws the stable resource failure for an exhausted scope-input budget. */
|
|
4891
|
-
var resourceLimitExceeded = (limit, limitMaximum, observedUsage) => {
|
|
4892
|
-
throw new CoreOperationException({
|
|
4893
|
-
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
4894
|
-
limit,
|
|
4895
|
-
limitMaximum,
|
|
4896
|
-
nextAction: "reduce-input-or-increase-limit",
|
|
4897
|
-
observedUsage,
|
|
4898
|
-
operation: "match-manifest-scope"
|
|
4899
|
-
});
|
|
4900
|
-
};
|
|
4901
|
-
/** Measures scalar UTF-8 bytes without allocating an encoded copy. */
|
|
4902
|
-
var measureUtf8ByteLength = (value) => {
|
|
4903
|
-
let byteLength = 0;
|
|
4904
|
-
for (const scalar of value) {
|
|
4905
|
-
const codePoint = scalar.codePointAt(0) ?? 0;
|
|
4906
|
-
byteLength += codePoint <= 127 ? 1 : codePoint <= 2047 ? 2 : codePoint <= 65535 ? 3 : 4;
|
|
4907
|
-
}
|
|
4908
|
-
return byteLength;
|
|
4909
|
-
};
|
|
4910
|
-
/**
|
|
4911
|
-
* Validates and snapshots one public manifest-scope input.
|
|
4912
|
-
* @param input The untrusted manifest document and changed logical paths.
|
|
4913
|
-
* @param limits The immutable Core resource limits.
|
|
4914
|
-
* @returns The detached manifest input and sorted unique repository paths.
|
|
4915
|
-
* @throws
|
|
4916
|
-
* - INVALID_REPOSITORY_PATH: A changed repository path is invalid.
|
|
4917
|
-
* - INVALID_ARGUMENT: The scope operation received an invalid argument.
|
|
4918
|
-
* - RESOURCE_LIMIT_EXCEEDED: The changed-path count or byte budget was exceeded.
|
|
4919
|
-
*/
|
|
4920
|
-
var normalizeManifestScopeInput = (input, limits) => {
|
|
4921
|
-
if (!isRecord(input)) return invalidArgument();
|
|
4922
|
-
const manifest = input["manifest"];
|
|
4923
|
-
const pathCandidates = input["paths"];
|
|
4924
|
-
if (!isRecord(manifest) || !Array.isArray(pathCandidates)) return invalidArgument();
|
|
4925
|
-
if (pathCandidates.length > limits.maxEntries) return resourceLimitExceeded("maxEntries", limits.maxEntries, pathCandidates.length);
|
|
4926
|
-
const uniquePaths = /* @__PURE__ */ new Set();
|
|
4927
|
-
let totalBytes = 0;
|
|
4928
|
-
for (const [index, candidate] of pathCandidates.entries()) {
|
|
4929
|
-
if (typeof candidate !== "string") return invalidArgument();
|
|
4930
|
-
const path = parseRepositoryPath(candidate);
|
|
4931
|
-
totalBytes += measureUtf8ByteLength(path) + (index === 0 ? 0 : 1);
|
|
4932
|
-
if (totalBytes > limits.maxTotalBytesRead) return resourceLimitExceeded("maxTotalBytesRead", limits.maxTotalBytesRead, totalBytes);
|
|
4933
|
-
uniquePaths.add(path);
|
|
4934
|
-
}
|
|
4935
|
-
return {
|
|
4936
|
-
manifest,
|
|
4937
|
-
paths: [...uniquePaths].sort(compareExactStrings)
|
|
4938
|
-
};
|
|
4939
|
-
};
|
|
4940
|
-
//#endregion
|
|
4941
|
-
//#region src/scope-matching/matching.ts
|
|
4942
|
-
var childPointer = (pointer, segment) => {
|
|
4943
|
-
return `${pointer}/${escapeJsonPointerSegment(segment)}`;
|
|
4944
|
-
};
|
|
4945
|
-
var createOwner = (kind, id, agentId = null) => ({
|
|
4946
|
-
agentId,
|
|
4947
|
-
id,
|
|
4948
|
-
kind
|
|
4949
|
-
});
|
|
4950
|
-
var compareOwners = (left, right) => {
|
|
4951
|
-
return compareExactStrings(left.kind, right.kind) || compareExactStrings(left.agentId ?? "", right.agentId ?? "") || compareExactStrings(left.id, right.id);
|
|
4952
|
-
};
|
|
4953
|
-
var getDeclarationValue = (declaration) => {
|
|
4954
|
-
return declaration.kind === "exact" ? declaration.path : declaration.pattern;
|
|
4955
|
-
};
|
|
4956
|
-
var compareDeclarations = (left, right) => {
|
|
4957
|
-
return compareOwners(left.owner, right.owner) || compareExactStrings(left.field, right.field) || compareExactStrings(getDeclarationValue(left.declaration), getDeclarationValue(right.declaration)) || compareExactStrings(left.pointer, right.pointer);
|
|
4958
|
-
};
|
|
4959
|
-
/** Adds one exact repository relationship to the normalized declaration collection. */
|
|
4960
|
-
var addExactDeclaration = (declarations, owner, field, pointer, reference) => {
|
|
4961
|
-
declarations.push({
|
|
4962
|
-
declaration: typeof reference === "string" ? {
|
|
4963
|
-
kind: "exact",
|
|
4964
|
-
path: reference,
|
|
4965
|
-
symbol: null
|
|
4966
|
-
} : {
|
|
4967
|
-
kind: "exact",
|
|
4968
|
-
path: reference.path,
|
|
4969
|
-
symbol: reference.symbol ?? null
|
|
4970
|
-
},
|
|
4971
|
-
field,
|
|
4972
|
-
owner,
|
|
4973
|
-
pointer
|
|
4974
|
-
});
|
|
4975
|
-
};
|
|
4976
|
-
/** Adds sorted repository references while preserving normalized declaration pointers. */
|
|
4977
|
-
var addReferenceDeclarations = (declarations, references, owner, field, pointer) => {
|
|
4978
|
-
for (const [index, reference] of (references ?? []).entries()) addExactDeclaration(declarations, owner, field, childPointer(pointer, String(index)), reference);
|
|
4979
|
-
};
|
|
4980
|
-
/** Adds exact and simple-glob impact relationships in normalized array order. */
|
|
4981
|
-
var addAffectedByDeclarations = (declarations, affectedBy, owner, pointer) => {
|
|
4982
|
-
for (const [index, pattern] of (affectedBy ?? []).entries()) declarations.push({
|
|
4983
|
-
declaration: pattern.includes("*") ? {
|
|
4984
|
-
kind: "glob",
|
|
4985
|
-
pattern
|
|
4986
|
-
} : {
|
|
4987
|
-
kind: "exact",
|
|
4988
|
-
path: pattern,
|
|
4989
|
-
symbol: null
|
|
4990
|
-
},
|
|
4991
|
-
field: "affectedBy",
|
|
4992
|
-
owner,
|
|
4993
|
-
pointer: childPointer(pointer, String(index))
|
|
4994
|
-
});
|
|
4995
|
-
};
|
|
4996
|
-
/** Adds project-level or agent-level unresolved requirement references. */
|
|
4997
|
-
var addUnresolvedDeclarations = (declarations, requirements, pointer, agentId) => {
|
|
4998
|
-
for (const requirementId of Object.keys(requirements ?? {}).sort(compareExactStrings)) {
|
|
4999
|
-
const requirement = requirements?.[requirementId];
|
|
5000
|
-
if (requirement === void 0) continue;
|
|
5001
|
-
const owner = createOwner("unresolved", requirementId, agentId);
|
|
5002
|
-
addReferenceDeclarations(declarations, requirement.related, owner, "related", childPointer(childPointer(pointer, requirementId), "related"));
|
|
5003
|
-
}
|
|
5004
|
-
};
|
|
5005
|
-
/** Adds exact and impact declarations owned by one tool or skill capability. */
|
|
5006
|
-
var addCapabilityDeclarations = (declarations, capabilityId, capability, agentId, pointer) => {
|
|
5007
|
-
const owner = createOwner(capability.kind, capabilityId, agentId);
|
|
5008
|
-
addExactDeclaration(declarations, owner, "implementation", childPointer(pointer, "implementation"), capability.value.implementation);
|
|
5009
|
-
if (capability.value.registration !== void 0) addExactDeclaration(declarations, owner, "registration", childPointer(pointer, "registration"), capability.value.registration);
|
|
5010
|
-
if (capability.kind === "tool") for (const field of ["inputSchema", "outputSchema"]) {
|
|
5011
|
-
const reference = capability.value[field];
|
|
5012
|
-
if (reference !== void 0) addExactDeclaration(declarations, owner, field, childPointer(pointer, field), reference);
|
|
5013
|
-
}
|
|
5014
|
-
addAffectedByDeclarations(declarations, capability.value.affectedBy, owner, childPointer(pointer, "affectedBy"));
|
|
5015
|
-
};
|
|
5016
|
-
/** Adds all exact and impact relationships owned by one registered agent. */
|
|
5017
|
-
var addAgentDeclarations = (declarations, agentId, agent) => {
|
|
5018
|
-
const pointer = childPointer("/agents", agentId);
|
|
5019
|
-
const owner = createOwner("agent", agentId, agentId);
|
|
5020
|
-
const bindingsPointer = childPointer(pointer, "bindings");
|
|
5021
|
-
for (const field of [
|
|
5022
|
-
"runtimeAgent",
|
|
5023
|
-
"inputSchema",
|
|
5024
|
-
"outputSchema",
|
|
5025
|
-
"instructionLoader"
|
|
5026
|
-
]) {
|
|
5027
|
-
const reference = agent.bindings?.[field];
|
|
5028
|
-
if (reference !== void 0) addExactDeclaration(declarations, owner, field, childPointer(bindingsPointer, field), reference);
|
|
5029
|
-
}
|
|
5030
|
-
for (const variableId of Object.keys(agent.bindings?.variableProviders ?? {}).sort(compareExactStrings)) {
|
|
5031
|
-
const reference = agent.bindings?.variableProviders?.[variableId];
|
|
5032
|
-
if (reference !== void 0) addExactDeclaration(declarations, owner, "variableProvider", childPointer(childPointer(bindingsPointer, "variableProviders"), variableId), reference);
|
|
5033
|
-
}
|
|
5034
|
-
addAffectedByDeclarations(declarations, agent.affectedBy, owner, childPointer(pointer, "affectedBy"));
|
|
5035
|
-
for (const capabilityId of Object.keys(agent.tools ?? {}).sort(compareExactStrings)) {
|
|
5036
|
-
const tool = agent.tools?.[capabilityId];
|
|
5037
|
-
if (tool !== void 0) addCapabilityDeclarations(declarations, capabilityId, {
|
|
5038
|
-
kind: "tool",
|
|
5039
|
-
value: tool
|
|
5040
|
-
}, agentId, childPointer(childPointer(pointer, "tools"), capabilityId));
|
|
5041
|
-
}
|
|
5042
|
-
for (const capabilityId of Object.keys(agent.skills ?? {}).sort(compareExactStrings)) {
|
|
5043
|
-
const skill = agent.skills?.[capabilityId];
|
|
5044
|
-
if (skill !== void 0) addCapabilityDeclarations(declarations, capabilityId, {
|
|
5045
|
-
kind: "skill",
|
|
5046
|
-
value: skill
|
|
5047
|
-
}, agentId, childPointer(childPointer(pointer, "skills"), capabilityId));
|
|
5048
|
-
}
|
|
5049
|
-
for (const [index, mirror] of (agent.mirrors ?? []).entries()) addExactDeclaration(declarations, owner, "mirrors", childPointer(childPointer(pointer, "mirrors"), String(index)), mirror);
|
|
5050
|
-
addUnresolvedDeclarations(declarations, agent.unresolved, childPointer(pointer, "unresolved"), agentId);
|
|
5051
|
-
};
|
|
5052
|
-
/** Collects every version 1 declaration that can establish changed-path relevance. */
|
|
5053
|
-
var collectDeclarations = (manifest) => {
|
|
5054
|
-
const declarations = [];
|
|
5055
|
-
for (const kind of ["context", "decision"]) {
|
|
5056
|
-
const relationships = kind === "context" ? manifest.context : manifest.decisions;
|
|
5057
|
-
for (const ownerId of Object.keys(relationships ?? {}).sort(compareExactStrings)) {
|
|
5058
|
-
const relationship = relationships?.[ownerId];
|
|
5059
|
-
if (relationship === void 0) continue;
|
|
5060
|
-
const owner = createOwner(kind, ownerId);
|
|
5061
|
-
const pointer = childPointer(kind === "context" ? "/context" : "/decisions", ownerId);
|
|
5062
|
-
addReferenceDeclarations(declarations, relationship.bindings, owner, "bindings", childPointer(pointer, "bindings"));
|
|
5063
|
-
addAffectedByDeclarations(declarations, relationship.affectedBy, owner, childPointer(pointer, "affectedBy"));
|
|
5064
|
-
}
|
|
5065
|
-
}
|
|
5066
|
-
addUnresolvedDeclarations(declarations, manifest.unresolved, "/unresolved", null);
|
|
5067
|
-
for (const agentId of Object.keys(manifest.agents ?? {}).sort(compareExactStrings)) {
|
|
5068
|
-
const agent = manifest.agents?.[agentId];
|
|
5069
|
-
if (agent !== void 0) addAgentDeclarations(declarations, agentId, agent);
|
|
5070
|
-
}
|
|
5071
|
-
return declarations.sort(compareDeclarations);
|
|
5072
|
-
};
|
|
5073
|
-
/** Tests a single-segment wildcard without regular-expression interpretation. */
|
|
5074
|
-
var matchesSegment = (pattern, value) => {
|
|
5075
|
-
let patternIndex = 0;
|
|
5076
|
-
let valueIndex = 0;
|
|
5077
|
-
let starIndex = -1;
|
|
5078
|
-
let starValueIndex = -1;
|
|
5079
|
-
while (valueIndex < value.length) {
|
|
5080
|
-
if (pattern[patternIndex] === value[valueIndex]) {
|
|
5081
|
-
patternIndex += 1;
|
|
5082
|
-
valueIndex += 1;
|
|
5083
|
-
continue;
|
|
5084
|
-
}
|
|
5085
|
-
if (pattern[patternIndex] === "*") {
|
|
5086
|
-
starIndex = patternIndex;
|
|
5087
|
-
starValueIndex = valueIndex;
|
|
5088
|
-
patternIndex += 1;
|
|
5089
|
-
continue;
|
|
5090
|
-
}
|
|
5091
|
-
if (starIndex === -1) return false;
|
|
5092
|
-
patternIndex = starIndex + 1;
|
|
5093
|
-
starValueIndex += 1;
|
|
5094
|
-
valueIndex = starValueIndex;
|
|
5095
|
-
}
|
|
5096
|
-
while (pattern[patternIndex] === "*") patternIndex += 1;
|
|
5097
|
-
return patternIndex === pattern.length;
|
|
5098
|
-
};
|
|
5099
|
-
/** Matches validated simple-glob segments with zero-or-more-segment globstars. */
|
|
5100
|
-
var matchesGlob = (patternSegments, path) => {
|
|
5101
|
-
const pathSegments = path.slice(1).split("/");
|
|
5102
|
-
let reachable = new Uint8Array(pathSegments.length + 1);
|
|
5103
|
-
reachable[0] = 1;
|
|
5104
|
-
for (const patternSegment of patternSegments) {
|
|
5105
|
-
const next = new Uint8Array(pathSegments.length + 1);
|
|
5106
|
-
if (patternSegment === "**") {
|
|
5107
|
-
let canReach = false;
|
|
5108
|
-
for (let index = 0; index < reachable.length; index += 1) {
|
|
5109
|
-
canReach ||= reachable[index] === 1;
|
|
5110
|
-
next[index] = canReach ? 1 : 0;
|
|
5111
|
-
}
|
|
5112
|
-
} else for (let index = 0; index < pathSegments.length; index += 1) if (reachable[index] === 1 && matchesSegment(patternSegment, pathSegments[index] ?? "")) next[index + 1] = 1;
|
|
5113
|
-
reachable = next;
|
|
5114
|
-
}
|
|
5115
|
-
return reachable[pathSegments.length] === 1;
|
|
5116
|
-
};
|
|
5117
|
-
/** Builds exact and first-segment glob indexes once for one parsed manifest. */
|
|
5118
|
-
var compileManifestScope = (manifest, limits) => {
|
|
5119
|
-
const declarations = collectDeclarations(manifest);
|
|
5120
|
-
if (declarations.length > limits.maxEntries) throw new CoreOperationException({
|
|
5121
|
-
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
5122
|
-
limit: "maxEntries",
|
|
5123
|
-
limitMaximum: limits.maxEntries,
|
|
5124
|
-
nextAction: "reduce-input-or-increase-limit",
|
|
5125
|
-
observedUsage: declarations.length,
|
|
5126
|
-
operation: "match-manifest-scope"
|
|
5127
|
-
});
|
|
5128
|
-
const exact = /* @__PURE__ */ new Map();
|
|
5129
|
-
const globalGlobs = [];
|
|
5130
|
-
const globsByFirstSegment = /* @__PURE__ */ new Map();
|
|
5131
|
-
for (const declaration of declarations) {
|
|
5132
|
-
if (declaration.declaration.kind === "exact") {
|
|
5133
|
-
const existing = exact.get(declaration.declaration.path) ?? [];
|
|
5134
|
-
existing.push(declaration);
|
|
5135
|
-
exact.set(declaration.declaration.path, existing);
|
|
5136
|
-
continue;
|
|
5137
|
-
}
|
|
5138
|
-
const segments = declaration.declaration.pattern.slice(1).split("/");
|
|
5139
|
-
const compiled = {
|
|
5140
|
-
declaration,
|
|
5141
|
-
segments
|
|
5142
|
-
};
|
|
5143
|
-
const firstSegment = segments[0] ?? "";
|
|
5144
|
-
if (firstSegment === "**" || firstSegment.includes("*")) globalGlobs.push(compiled);
|
|
5145
|
-
else {
|
|
5146
|
-
const existing = globsByFirstSegment.get(firstSegment) ?? [];
|
|
5147
|
-
existing.push(compiled);
|
|
5148
|
-
globsByFirstSegment.set(firstSegment, existing);
|
|
5149
|
-
}
|
|
5150
|
-
}
|
|
5151
|
-
return {
|
|
5152
|
-
declarations,
|
|
5153
|
-
exact,
|
|
5154
|
-
globalGlobs,
|
|
5155
|
-
globsByFirstSegment
|
|
5156
|
-
};
|
|
5157
|
-
};
|
|
5158
|
-
var compareMatches = (left, right) => {
|
|
5159
|
-
return compareOwners(left.owner, right.owner) || compareExactStrings(left.field, right.field) || compareExactStrings(getDeclarationValue(left.declaration), getDeclarationValue(right.declaration)) || compareExactStrings(left.inputPath, right.inputPath) || compareExactStrings(left.pointer, right.pointer);
|
|
5160
|
-
};
|
|
5161
|
-
var createMatch = (inputPath, relationship) => ({
|
|
5162
|
-
declaration: relationship.declaration,
|
|
5163
|
-
field: relationship.field,
|
|
5164
|
-
inputPath,
|
|
5165
|
-
owner: relationship.owner,
|
|
5166
|
-
pointer: relationship.pointer
|
|
5167
|
-
});
|
|
5168
|
-
/** Adds one match without ever allocating beyond the operation entry budget. */
|
|
5169
|
-
var addMatch = (matches, inputPath, relationship, limits) => {
|
|
5170
|
-
if (matches.length >= limits.maxEntries) throw new CoreOperationException({
|
|
5171
|
-
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
5172
|
-
limit: "maxEntries",
|
|
5173
|
-
limitMaximum: limits.maxEntries,
|
|
5174
|
-
nextAction: "reduce-input-or-increase-limit",
|
|
5175
|
-
observedUsage: matches.length + 1,
|
|
5176
|
-
operation: "match-manifest-scope"
|
|
5177
|
-
});
|
|
5178
|
-
matches.push(createMatch(inputPath, relationship));
|
|
5179
|
-
};
|
|
5180
|
-
/** Appends matches from one precompiled glob bucket without copying the bucket. */
|
|
5181
|
-
var addGlobMatches = (matches, inputPath, declarations, limits) => {
|
|
5182
|
-
for (const compiled of declarations) if (matchesGlob(compiled.segments, inputPath)) addMatch(matches, inputPath, compiled.declaration, limits);
|
|
5183
|
-
};
|
|
5184
|
-
/** Creates the canonical digest of the sorted unique changed-path set. */
|
|
5185
|
-
var calculateManifestScopeInputDigest = async (paths) => {
|
|
5186
|
-
const value = paths.join("\0");
|
|
5187
|
-
return calculateNormalizedTextDigest({
|
|
5188
|
-
scalarLength: countUnicodeScalars$1(value),
|
|
5189
|
-
utf8ByteLength: measureUtf8ByteLength(value),
|
|
5190
|
-
value
|
|
5191
|
-
});
|
|
5192
|
-
};
|
|
5193
|
-
/**
|
|
5194
|
-
* Matches normalized changed paths against one valid version 1 manifest.
|
|
5195
|
-
* @param manifest The parsed and validated manifest value.
|
|
5196
|
-
* @param paths Sorted unique repository-logical changed paths.
|
|
5197
|
-
* @param limits The immutable Core operation limits.
|
|
5198
|
-
* @returns Frozen content-free matches and stable aggregate counts.
|
|
5199
|
-
* @throws
|
|
5200
|
-
* - RESOURCE_LIMIT_EXCEEDED: The declaration or match count exceeded `maxEntries`.
|
|
5201
|
-
*/
|
|
5202
|
-
var matchParsedManifestScope = (manifest, paths, limits) => {
|
|
5203
|
-
const compiled = compileManifestScope(manifest, limits);
|
|
5204
|
-
const matches = [];
|
|
5205
|
-
const matchedOwners = /* @__PURE__ */ new Set();
|
|
5206
|
-
const matchedPaths = /* @__PURE__ */ new Set();
|
|
5207
|
-
for (const path of paths) {
|
|
5208
|
-
const firstSegment = path.slice(1).split("/", 1)[0] ?? "";
|
|
5209
|
-
const exactDeclarations = compiled.exact.get(path) ?? [];
|
|
5210
|
-
for (const relationship of exactDeclarations) addMatch(matches, path, relationship, limits);
|
|
5211
|
-
addGlobMatches(matches, path, compiled.globalGlobs, limits);
|
|
5212
|
-
addGlobMatches(matches, path, compiled.globsByFirstSegment.get(firstSegment) ?? [], limits);
|
|
5213
|
-
}
|
|
5214
|
-
matches.sort(compareMatches);
|
|
5215
|
-
for (const match of matches) {
|
|
5216
|
-
matchedOwners.add(`${match.owner.kind}\0${match.owner.agentId ?? ""}\0${match.owner.id}`);
|
|
5217
|
-
matchedPaths.add(match.inputPath);
|
|
5218
|
-
}
|
|
5219
|
-
return freezeRecursively({
|
|
5220
|
-
counts: {
|
|
5221
|
-
declarations: compiled.declarations.length,
|
|
5222
|
-
inputPaths: paths.length,
|
|
5223
|
-
matchedOwners: matchedOwners.size,
|
|
5224
|
-
matchedPaths: matchedPaths.size,
|
|
5225
|
-
matches: matches.length
|
|
5226
|
-
},
|
|
5227
|
-
matches
|
|
5228
|
-
});
|
|
5229
|
-
};
|
|
5230
|
-
//#endregion
|
|
5231
|
-
//#region src/scope-matching/scope.ts
|
|
5232
|
-
/**
|
|
5233
|
-
* Parses a manifest and matches its repository relationships against changed logical paths.
|
|
5234
|
-
* @param input The canonical manifest document and untrusted changed-path collection.
|
|
5235
|
-
* @param options The immutable Core operation options.
|
|
5236
|
-
* @returns A promise resolving to frozen content-free scope metadata and matches.
|
|
5237
|
-
* @throws
|
|
5238
|
-
* - INVALID_REPOSITORY_PATH: The manifest path or a changed repository path is invalid.
|
|
5239
|
-
* - INVALID_ARGUMENT: The scope operation received an invalid argument.
|
|
5240
|
-
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
5241
|
-
*/
|
|
5242
|
-
var matchManifestScope = async (input, options) => {
|
|
5243
|
-
const normalized = normalizeManifestScopeInput(input, options.limits);
|
|
5244
|
-
const inputDigest = await calculateManifestScopeInputDigest(normalized.paths);
|
|
5245
|
-
const parsed = await parseManifestDocument(normalized.manifest, options, "match-manifest-scope");
|
|
5246
|
-
if (!parsed.valid || parsed.asset === null || parsed.manifest === null) return freezeRecursively({
|
|
5247
|
-
counts: {
|
|
5248
|
-
declarations: 0,
|
|
5249
|
-
inputPaths: normalized.paths.length,
|
|
5250
|
-
matchedOwners: 0,
|
|
5251
|
-
matchedPaths: 0,
|
|
5252
|
-
matches: 0
|
|
5253
|
-
},
|
|
5254
|
-
diagnostics: parsed.diagnostics,
|
|
5255
|
-
inputDigest,
|
|
5256
|
-
manifestDigest: null,
|
|
5257
|
-
matches: [],
|
|
5258
|
-
relevant: false,
|
|
5259
|
-
valid: false
|
|
5260
|
-
});
|
|
5261
|
-
const matched = matchParsedManifestScope(parsed.manifest, normalized.paths, options.limits);
|
|
5262
|
-
return freezeRecursively({
|
|
5263
|
-
counts: matched.counts,
|
|
5264
|
-
diagnostics: [],
|
|
5265
|
-
inputDigest,
|
|
5266
|
-
manifestDigest: parsed.asset.digest,
|
|
5267
|
-
matches: matched.matches,
|
|
5268
|
-
relevant: matched.matches.length > 0,
|
|
5269
|
-
valid: true
|
|
5270
|
-
});
|
|
5271
|
-
};
|
|
5272
|
-
//#endregion
|
|
5273
3333
|
//#region src/core/index.ts
|
|
5274
3334
|
var core_exports = /* @__PURE__ */ __exportAll({ createCore: () => createCore });
|
|
5275
3335
|
/**
|
|
5276
3336
|
* Creates one immutable Core instance from detached configuration snapshots.
|
|
5277
|
-
* @param options Optional
|
|
3337
|
+
* @param options Optional resource-limit overrides.
|
|
5278
3338
|
* @returns A frozen Core instance safe for concurrent independent operations.
|
|
5279
3339
|
* @throws
|
|
5280
|
-
* - DUPLICATE_ADAPTER_ID: A runtime adapter ID is registered more than once.
|
|
5281
|
-
* - RESERVED_ADAPTER_ID: A reserved runtime adapter ID was supplied.
|
|
5282
|
-
* - INVALID_ADAPTER_DEFINITION: A runtime adapter definition is invalid.
|
|
5283
3340
|
* - INVALID_RESOURCE_LIMIT: A Core resource limit is invalid.
|
|
5284
3341
|
*/
|
|
5285
3342
|
var createCore = (options) => {
|
|
5286
3343
|
const snapshot = normalizeCoreOptions(options);
|
|
5287
3344
|
return freezeRecursively({
|
|
5288
3345
|
calculateContentDigest: (input) => {
|
|
5289
|
-
|
|
3346
|
+
const operation = createCoreOperationOptionsSnapshot(snapshot);
|
|
3347
|
+
return calculateContentDigest(input, operation.limits);
|
|
5290
3348
|
},
|
|
5291
3349
|
createProjectInspection: (input) => createProjectInspection(input, createCoreOperationOptionsSnapshot(snapshot)),
|
|
5292
3350
|
validateProject: (input) => validateProject(input, createCoreOperationOptionsSnapshot(snapshot)),
|
|
5293
3351
|
matchManifestScope: (input) => matchManifestScope(input, createCoreOperationOptionsSnapshot(snapshot)),
|
|
5294
3352
|
normalizeText: (input) => {
|
|
5295
|
-
|
|
3353
|
+
const operation = createCoreOperationOptionsSnapshot(snapshot);
|
|
3354
|
+
return normalizeTextDocument(input, operation.limits, "normalize-text");
|
|
5296
3355
|
},
|
|
5297
3356
|
parseDecision: (input) => parseDecisionDocument(input, createCoreOperationOptionsSnapshot(snapshot)),
|
|
5298
3357
|
parseManifest: (input) => parseManifestDocument(input, createCoreOperationOptionsSnapshot(snapshot)),
|
|
@@ -5300,6 +3359,6 @@ var createCore = (options) => {
|
|
|
5300
3359
|
});
|
|
5301
3360
|
};
|
|
5302
3361
|
//#endregion
|
|
5303
|
-
export { createCore as n, core_exports as t };
|
|
3362
|
+
export { createCore as n, parseIntegrationBlock as r, core_exports as t };
|
|
5304
3363
|
|
|
5305
|
-
//# sourceMappingURL=core-
|
|
3364
|
+
//# sourceMappingURL=core-Cdeiu6xG.js.map
|