@moldea.ai/core 5.0.1 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -11
- package/dist/analysis-worker.js +180 -0
- package/dist/analysis-worker.js.map +1 -0
- package/dist/binding-coverage/index.d.ts +26 -0
- package/dist/binding-coverage/index.d.ts.map +1 -0
- package/dist/chunks/core-Cdeiu6xG.js +3364 -0
- package/dist/chunks/core-Cdeiu6xG.js.map +1 -0
- package/dist/chunks/errors-BE4DS3Ak.js +435 -0
- package/dist/chunks/errors-BE4DS3Ak.js.map +1 -0
- package/dist/chunks/{exceptions-HS9ofVy2.js → exceptions-IXsorE8t.js} +27 -28
- package/dist/chunks/exceptions-IXsorE8t.js.map +1 -0
- package/dist/chunks/lifecycle-D_RvxhDC.js +67 -0
- package/dist/chunks/lifecycle-D_RvxhDC.js.map +1 -0
- package/dist/chunks/options-5x9gu2Qb.js +604 -0
- package/dist/chunks/options-5x9gu2Qb.js.map +1 -0
- package/dist/chunks/repository-rpc-B_y0Kspf.js +124 -0
- package/dist/chunks/repository-rpc-B_y0Kspf.js.map +1 -0
- 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 +37 -27
- 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 +25 -10
- 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 +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -5776
- 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 +4 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node-inspection/analysis-worker.d.ts +2 -0
- package/dist/node-inspection/analysis-worker.d.ts.map +1 -0
- package/dist/node-inspection/client.d.ts +28 -0
- package/dist/node-inspection/client.d.ts.map +1 -0
- package/dist/node-inspection/constants.d.ts +21 -0
- package/dist/node-inspection/constants.d.ts.map +1 -0
- package/dist/node-inspection/errors.d.ts +11 -0
- package/dist/node-inspection/errors.d.ts.map +1 -0
- package/dist/node-inspection/lifecycle.d.ts +15 -0
- package/dist/node-inspection/lifecycle.d.ts.map +1 -0
- package/dist/node-inspection/protocol.d.ts +20 -0
- package/dist/node-inspection/protocol.d.ts.map +1 -0
- package/dist/node-inspection/repository-rpc.d.ts +28 -0
- package/dist/node-inspection/repository-rpc.d.ts.map +1 -0
- package/dist/node-inspection/runner.d.ts +2 -0
- package/dist/node-inspection/runner.d.ts.map +1 -0
- package/dist/node-inspection/types.d.ts +95 -0
- package/dist/node-inspection/types.d.ts.map +1 -0
- package/dist/node-runner.js +149 -0
- package/dist/node-runner.js.map +1 -0
- package/dist/node.js +335 -0
- package/dist/node.js.map +1 -0
- package/dist/options/index.d.ts +2 -14
- package/dist/options/index.d.ts.map +1 -1
- package/dist/project-inspection/index.d.ts +21 -1
- package/dist/project-inspection/index.d.ts.map +1 -1
- package/dist/project-validation/index.d.ts +33 -11
- 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 +14 -6
- package/dist/adapter/index.d.ts +0 -131
- 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 -31
- 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-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 -115
- package/dist/adapter.js.map +0 -1
- package/dist/chunks/exceptions-HS9ofVy2.js.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,1827 @@
|
|
|
1
|
+
import { A as ACCEPTABLE_WARNING_CODES, C as isSimpleGlob, D as parseManifestPath, M as RECOGNIZED_RUNTIME_IDS, O as sortRepositoryReferences, S as isRuntimeGuidancePath, T as isVariableId, _ as isDecisionPath, a as escapeJsonPointerSegment, b as isRepositorySymbol, c as freezeRecursively, d as hasNonWhitespace, f as hasUnsupportedGlobMetacharacter, g as isContextPath, h as isCapabilityDescription, i as createCoreDiagnosticCollector, l as compareExactStrings, m as isCanonicalMoldeaPath, p as isCanonicalManifestPath, s as createNullPrototypeRecord, t as createCoreOperationOptionsSnapshot, u as countUnicodeScalars$1, v as isMirrorPath, w as isStableId, x as isReservedId, y as isNonEmptySingleLine } from "./options-5x9gu2Qb.js";
|
|
2
|
+
import { n as CoreOperationException } from "./exceptions-IXsorE8t.js";
|
|
3
|
+
import { parseRepositoryPath } from "@moldea.ai/repository";
|
|
4
|
+
import { Parser, isAlias, isMap, isScalar, isSeq, parseAllDocuments } from "yaml";
|
|
5
|
+
//#region src/text/index.ts
|
|
6
|
+
var encoder = new TextEncoder();
|
|
7
|
+
var decoder = new TextDecoder("utf-8", {
|
|
8
|
+
fatal: true,
|
|
9
|
+
ignoreBOM: true
|
|
10
|
+
});
|
|
11
|
+
var isRecord$1 = (value) => {
|
|
12
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Measures valid scalar UTF-8 bytes and stops once the operation budget is exceeded.
|
|
16
|
+
* @param value The decoded string to measure without lossy replacement.
|
|
17
|
+
* @param maximumByteLength The threshold after which measurement may stop early.
|
|
18
|
+
* @returns The measured bytes, a value above the threshold, or `null` for invalid Unicode.
|
|
19
|
+
*/
|
|
20
|
+
var measureScalarUtf8ByteLength = (value, maximumByteLength) => {
|
|
21
|
+
let byteLength = 0;
|
|
22
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
23
|
+
const codeUnit = value.charCodeAt(index);
|
|
24
|
+
if (codeUnit >= 55296 && codeUnit <= 56319) {
|
|
25
|
+
if (index + 1 >= value.length) return null;
|
|
26
|
+
const nextCodeUnit = value.charCodeAt(index + 1);
|
|
27
|
+
if (nextCodeUnit < 56320 || nextCodeUnit > 57343) return null;
|
|
28
|
+
byteLength += 4;
|
|
29
|
+
if (byteLength > maximumByteLength) return byteLength;
|
|
30
|
+
index += 1;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (codeUnit >= 56320 && codeUnit <= 57343) return null;
|
|
34
|
+
byteLength += codeUnit <= 127 ? 1 : codeUnit <= 2047 ? 2 : 3;
|
|
35
|
+
if (byteLength > maximumByteLength) return byteLength;
|
|
36
|
+
}
|
|
37
|
+
return byteLength;
|
|
38
|
+
};
|
|
39
|
+
var countUnicodeScalars = (value) => {
|
|
40
|
+
let count = 0;
|
|
41
|
+
for (let index = 0; index < value.length; count += 1) {
|
|
42
|
+
const codePoint = value.codePointAt(index);
|
|
43
|
+
if (codePoint === void 0) break;
|
|
44
|
+
index += codePoint > 65535 ? 2 : 1;
|
|
45
|
+
}
|
|
46
|
+
return count;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Collects every normalized NUL location or rejects when the diagnostic budget is exhausted.
|
|
50
|
+
* @param value The normalized scalar text to inspect.
|
|
51
|
+
* @param path The logical document path attached to each diagnostic.
|
|
52
|
+
* @param diagnostics The operation collector receiving every NUL diagnostic.
|
|
53
|
+
* @throws
|
|
54
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
55
|
+
*/
|
|
56
|
+
var collectNulDiagnostics = (value, path, diagnostics) => {
|
|
57
|
+
let column = 1;
|
|
58
|
+
let line = 1;
|
|
59
|
+
let offset = 0;
|
|
60
|
+
for (const scalar of value) {
|
|
61
|
+
if (scalar === "\0") diagnostics.add({
|
|
62
|
+
code: "MOLDEA_TEXT_NUL_FORBIDDEN",
|
|
63
|
+
path,
|
|
64
|
+
range: {
|
|
65
|
+
end: {
|
|
66
|
+
column: column + 1,
|
|
67
|
+
line,
|
|
68
|
+
offset: offset + 1
|
|
69
|
+
},
|
|
70
|
+
start: {
|
|
71
|
+
column,
|
|
72
|
+
line,
|
|
73
|
+
offset
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
if (scalar === "\n") {
|
|
78
|
+
column = 1;
|
|
79
|
+
line += 1;
|
|
80
|
+
} else column += 1;
|
|
81
|
+
offset += 1;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
var invalidArgument$1 = (operation) => {
|
|
85
|
+
throw new CoreOperationException({
|
|
86
|
+
code: "INVALID_ARGUMENT",
|
|
87
|
+
operation
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
var enforceFileLimit = (byteLength, limits, operation, limit) => {
|
|
91
|
+
if (byteLength <= limits[limit]) return;
|
|
92
|
+
throw new CoreOperationException({
|
|
93
|
+
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
94
|
+
limit,
|
|
95
|
+
limitMaximum: limits[limit],
|
|
96
|
+
nextAction: "reduce-input-or-increase-limit",
|
|
97
|
+
observedUsage: byteLength,
|
|
98
|
+
operation
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
var invalidResult = (diagnostics) => {
|
|
102
|
+
return freezeRecursively({
|
|
103
|
+
diagnostics: [...diagnostics],
|
|
104
|
+
text: null,
|
|
105
|
+
valid: false
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Validates one public text input, enforces its source-byte budget, and decodes strict UTF-8.
|
|
110
|
+
* @param input The untrusted public text-document input.
|
|
111
|
+
* @param limits The immutable Core resource limits.
|
|
112
|
+
* @param operation The public operation requesting the input.
|
|
113
|
+
* @param limit The source-byte limit applied by the operation.
|
|
114
|
+
* @param diagnostics The operation collector receiving text diagnostics.
|
|
115
|
+
* @returns Decoded text or a frozen structural failure result.
|
|
116
|
+
* @throws
|
|
117
|
+
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
118
|
+
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
119
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
120
|
+
*/
|
|
121
|
+
var readInput = (input, limits, operation, limit, diagnostics) => {
|
|
122
|
+
if (!isRecord$1(input)) return invalidArgument$1(operation);
|
|
123
|
+
const pathCandidate = input["path"];
|
|
124
|
+
const content = input["content"];
|
|
125
|
+
if (typeof pathCandidate !== "string" || typeof content !== "string" && !(content instanceof Uint8Array)) return invalidArgument$1(operation);
|
|
126
|
+
const path = parseRepositoryPath(pathCandidate);
|
|
127
|
+
if (typeof content === "string") {
|
|
128
|
+
const byteLength = measureScalarUtf8ByteLength(content, limits[limit]);
|
|
129
|
+
if (byteLength === null) {
|
|
130
|
+
diagnostics.add({
|
|
131
|
+
code: "MOLDEA_TEXT_INVALID_UNICODE",
|
|
132
|
+
path
|
|
133
|
+
});
|
|
134
|
+
return invalidResult(diagnostics.finalize());
|
|
135
|
+
}
|
|
136
|
+
enforceFileLimit(byteLength, limits, operation, limit);
|
|
137
|
+
return {
|
|
138
|
+
path,
|
|
139
|
+
value: content
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
enforceFileLimit(content.byteLength, limits, operation, limit);
|
|
143
|
+
const bytes = new Uint8Array(content);
|
|
144
|
+
try {
|
|
145
|
+
return {
|
|
146
|
+
path,
|
|
147
|
+
value: decoder.decode(bytes)
|
|
148
|
+
};
|
|
149
|
+
} catch {
|
|
150
|
+
diagnostics.add({
|
|
151
|
+
code: "MOLDEA_TEXT_INVALID_UTF8",
|
|
152
|
+
path
|
|
153
|
+
});
|
|
154
|
+
return invalidResult(diagnostics.finalize());
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Validates and normalizes one text document under an operation-specific resource budget.
|
|
159
|
+
* @param input The logical path and decoded string or exact source bytes.
|
|
160
|
+
* @param limits The immutable Core resource limits.
|
|
161
|
+
* @param operation The public Core operation requesting normalization.
|
|
162
|
+
* @param limit The source-byte limit applied by the operation.
|
|
163
|
+
* @returns A frozen normalized result or structural text diagnostics.
|
|
164
|
+
* @throws
|
|
165
|
+
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
166
|
+
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
167
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
168
|
+
*/
|
|
169
|
+
var normalizeTextDocument = (input, limits, operation, limit = "maxFileBytes") => {
|
|
170
|
+
const diagnostics = createCoreDiagnosticCollector(limits, operation);
|
|
171
|
+
const decoded = readInput(input, limits, operation, limit, diagnostics);
|
|
172
|
+
if ("valid" in decoded) return decoded;
|
|
173
|
+
const value = (decoded.value.startsWith("") ? decoded.value.slice(1) : decoded.value).replace(/\r\n?/gu, "\n");
|
|
174
|
+
collectNulDiagnostics(value, decoded.path, diagnostics);
|
|
175
|
+
if (diagnostics.size > 0) return invalidResult(diagnostics.finalize());
|
|
176
|
+
const text = freezeRecursively({
|
|
177
|
+
scalarLength: countUnicodeScalars(value),
|
|
178
|
+
utf8ByteLength: encoder.encode(value).byteLength,
|
|
179
|
+
value
|
|
180
|
+
});
|
|
181
|
+
return freezeRecursively({
|
|
182
|
+
diagnostics: [],
|
|
183
|
+
text,
|
|
184
|
+
valid: true
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
var toLowercaseHex = (bytes) => {
|
|
188
|
+
let value = "";
|
|
189
|
+
for (const byte of bytes) value += byte.toString(16).padStart(2, "0");
|
|
190
|
+
return value;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Calculates the canonical digest for already-normalized text.
|
|
194
|
+
* @param text The validated normalized text to encode and hash.
|
|
195
|
+
* @returns A promise resolving to the canonical lowercase SHA-256 digest.
|
|
196
|
+
*/
|
|
197
|
+
var calculateNormalizedTextDigest = async (text) => {
|
|
198
|
+
const bytes = encoder.encode(text.value);
|
|
199
|
+
return `sha256:${toLowercaseHex(new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", bytes)))}`;
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* Calculates the normalized SHA-256 digest for one text document.
|
|
203
|
+
* @param input The logical path and decoded string or exact source bytes.
|
|
204
|
+
* @param limits The immutable Core resource limits.
|
|
205
|
+
* @returns A promise resolving to a frozen digest result or structural text diagnostics.
|
|
206
|
+
* @throws
|
|
207
|
+
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
208
|
+
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
209
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
210
|
+
*/
|
|
211
|
+
var calculateContentDigest = async (input, limits) => {
|
|
212
|
+
const normalized = normalizeTextDocument(input, limits, "calculate-content-digest");
|
|
213
|
+
if (!normalized.valid || normalized.text === null) return freezeRecursively({
|
|
214
|
+
diagnostics: normalized.diagnostics,
|
|
215
|
+
digest: null,
|
|
216
|
+
text: null,
|
|
217
|
+
valid: false
|
|
218
|
+
});
|
|
219
|
+
const digest = await calculateNormalizedTextDigest(normalized.text);
|
|
220
|
+
return freezeRecursively({
|
|
221
|
+
diagnostics: [],
|
|
222
|
+
digest,
|
|
223
|
+
text: normalized.text,
|
|
224
|
+
valid: true
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/scope-matching/validations.ts
|
|
229
|
+
var isRecord = (value) => {
|
|
230
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
231
|
+
};
|
|
232
|
+
/** Throws the stable invalid-argument failure for malformed scope input. */
|
|
233
|
+
var invalidArgument = () => {
|
|
234
|
+
throw new CoreOperationException({
|
|
235
|
+
code: "INVALID_ARGUMENT",
|
|
236
|
+
operation: "match-manifest-scope"
|
|
237
|
+
});
|
|
238
|
+
};
|
|
239
|
+
/** Throws the stable resource failure for an exhausted scope-input budget. */
|
|
240
|
+
var resourceLimitExceeded = (limit, limitMaximum, observedUsage) => {
|
|
241
|
+
throw new CoreOperationException({
|
|
242
|
+
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
243
|
+
limit,
|
|
244
|
+
limitMaximum,
|
|
245
|
+
nextAction: "reduce-input-or-increase-limit",
|
|
246
|
+
observedUsage,
|
|
247
|
+
operation: "match-manifest-scope"
|
|
248
|
+
});
|
|
249
|
+
};
|
|
250
|
+
/** Measures scalar UTF-8 bytes without allocating an encoded copy. */
|
|
251
|
+
var measureUtf8ByteLength = (value) => {
|
|
252
|
+
let byteLength = 0;
|
|
253
|
+
for (const scalar of value) {
|
|
254
|
+
const codePoint = scalar.codePointAt(0) ?? 0;
|
|
255
|
+
byteLength += codePoint <= 127 ? 1 : codePoint <= 2047 ? 2 : codePoint <= 65535 ? 3 : 4;
|
|
256
|
+
}
|
|
257
|
+
return byteLength;
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* Validates and snapshots one public manifest-scope input.
|
|
261
|
+
* @param input The untrusted manifest document and changed logical paths.
|
|
262
|
+
* @param limits The immutable Core resource limits.
|
|
263
|
+
* @returns The detached manifest input and sorted unique repository paths.
|
|
264
|
+
* @throws
|
|
265
|
+
* - INVALID_REPOSITORY_PATH: A changed repository path is invalid.
|
|
266
|
+
* - INVALID_ARGUMENT: The scope operation received an invalid argument.
|
|
267
|
+
* - RESOURCE_LIMIT_EXCEEDED: The changed-path count or byte budget was exceeded.
|
|
268
|
+
*/
|
|
269
|
+
var normalizeManifestScopeInput = (input, limits) => {
|
|
270
|
+
if (!isRecord(input)) return invalidArgument();
|
|
271
|
+
const manifest = input["manifest"];
|
|
272
|
+
const pathCandidates = input["paths"];
|
|
273
|
+
if (!isRecord(manifest) || !Array.isArray(pathCandidates)) return invalidArgument();
|
|
274
|
+
if (pathCandidates.length > limits.maxEntries) return resourceLimitExceeded("maxEntries", limits.maxEntries, pathCandidates.length);
|
|
275
|
+
const uniquePaths = /* @__PURE__ */ new Set();
|
|
276
|
+
let totalBytes = 0;
|
|
277
|
+
for (const [index, candidate] of pathCandidates.entries()) {
|
|
278
|
+
if (typeof candidate !== "string") return invalidArgument();
|
|
279
|
+
const path = parseRepositoryPath(candidate);
|
|
280
|
+
totalBytes += measureUtf8ByteLength(path) + (index === 0 ? 0 : 1);
|
|
281
|
+
if (totalBytes > limits.maxTotalBytesRead) return resourceLimitExceeded("maxTotalBytesRead", limits.maxTotalBytesRead, totalBytes);
|
|
282
|
+
uniquePaths.add(path);
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
manifest,
|
|
286
|
+
paths: [...uniquePaths].sort(compareExactStrings)
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
//#endregion
|
|
290
|
+
//#region src/scope-matching/patterns.ts
|
|
291
|
+
/** Tests a single-segment wildcard without regular-expression interpretation. */
|
|
292
|
+
var matchesSegment = (pattern, value) => {
|
|
293
|
+
let patternIndex = 0;
|
|
294
|
+
let valueIndex = 0;
|
|
295
|
+
let starIndex = -1;
|
|
296
|
+
let starValueIndex = -1;
|
|
297
|
+
while (valueIndex < value.length) {
|
|
298
|
+
if (pattern[patternIndex] === value[valueIndex]) {
|
|
299
|
+
patternIndex += 1;
|
|
300
|
+
valueIndex += 1;
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
if (pattern[patternIndex] === "*") {
|
|
304
|
+
starIndex = patternIndex;
|
|
305
|
+
starValueIndex = valueIndex;
|
|
306
|
+
patternIndex += 1;
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
if (starIndex === -1) return false;
|
|
310
|
+
patternIndex = starIndex + 1;
|
|
311
|
+
starValueIndex += 1;
|
|
312
|
+
valueIndex = starValueIndex;
|
|
313
|
+
}
|
|
314
|
+
while (pattern[patternIndex] === "*") patternIndex += 1;
|
|
315
|
+
return patternIndex === pattern.length;
|
|
316
|
+
};
|
|
317
|
+
/** Matches validated simple-glob segments with zero-or-more-segment globstars. */
|
|
318
|
+
var matchesRepositoryGlob = (patternSegments, path) => {
|
|
319
|
+
const pathSegments = path.slice(1).split("/");
|
|
320
|
+
let reachable = new Uint8Array(pathSegments.length + 1);
|
|
321
|
+
reachable[0] = 1;
|
|
322
|
+
for (const patternSegment of patternSegments) {
|
|
323
|
+
const next = new Uint8Array(pathSegments.length + 1);
|
|
324
|
+
if (patternSegment === "**") {
|
|
325
|
+
let canReach = false;
|
|
326
|
+
for (let index = 0; index < reachable.length; index += 1) {
|
|
327
|
+
canReach ||= reachable[index] === 1;
|
|
328
|
+
next[index] = canReach ? 1 : 0;
|
|
329
|
+
}
|
|
330
|
+
} else for (let index = 0; index < pathSegments.length; index += 1) if (reachable[index] === 1 && matchesSegment(patternSegment, pathSegments[index] ?? "")) next[index + 1] = 1;
|
|
331
|
+
reachable = next;
|
|
332
|
+
}
|
|
333
|
+
return reachable[pathSegments.length] === 1;
|
|
334
|
+
};
|
|
335
|
+
//#endregion
|
|
336
|
+
//#region src/scope-matching/matching.ts
|
|
337
|
+
var childPointer$1 = (pointer, segment) => {
|
|
338
|
+
return `${pointer}/${escapeJsonPointerSegment(segment)}`;
|
|
339
|
+
};
|
|
340
|
+
var createOwner = (kind, id, agentId = null) => ({
|
|
341
|
+
agentId,
|
|
342
|
+
id,
|
|
343
|
+
kind
|
|
344
|
+
});
|
|
345
|
+
var compareOwners = (left, right) => {
|
|
346
|
+
return compareExactStrings(left.kind, right.kind) || compareExactStrings(left.agentId ?? "", right.agentId ?? "") || compareExactStrings(left.id, right.id);
|
|
347
|
+
};
|
|
348
|
+
var getDeclarationValue = (declaration) => {
|
|
349
|
+
return declaration.kind === "exact" ? declaration.path : declaration.pattern;
|
|
350
|
+
};
|
|
351
|
+
var compareDeclarations = (left, right) => {
|
|
352
|
+
return compareOwners(left.owner, right.owner) || compareExactStrings(left.field, right.field) || compareExactStrings(getDeclarationValue(left.declaration), getDeclarationValue(right.declaration)) || compareExactStrings(left.pointer, right.pointer);
|
|
353
|
+
};
|
|
354
|
+
/** Adds one exact repository relationship to the normalized declaration collection. */
|
|
355
|
+
var addExactDeclaration = (declarations, owner, field, pointer, reference) => {
|
|
356
|
+
declarations.push({
|
|
357
|
+
declaration: typeof reference === "string" ? {
|
|
358
|
+
kind: "exact",
|
|
359
|
+
path: reference,
|
|
360
|
+
symbol: null
|
|
361
|
+
} : {
|
|
362
|
+
kind: "exact",
|
|
363
|
+
path: reference.path,
|
|
364
|
+
symbol: reference.symbol ?? null
|
|
365
|
+
},
|
|
366
|
+
field,
|
|
367
|
+
owner,
|
|
368
|
+
pointer
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
/** Adds sorted repository references while preserving normalized declaration pointers. */
|
|
372
|
+
var addReferenceDeclarations = (declarations, references, owner, field, pointer) => {
|
|
373
|
+
for (const [index, reference] of (references ?? []).entries()) addExactDeclaration(declarations, owner, field, childPointer$1(pointer, String(index)), reference);
|
|
374
|
+
};
|
|
375
|
+
/** Adds exact and simple-glob impact relationships in normalized array order. */
|
|
376
|
+
var addAffectedByDeclarations = (declarations, affectedBy, owner, pointer) => {
|
|
377
|
+
for (const [index, pattern] of (affectedBy ?? []).entries()) declarations.push({
|
|
378
|
+
declaration: pattern.includes("*") ? {
|
|
379
|
+
kind: "glob",
|
|
380
|
+
pattern
|
|
381
|
+
} : {
|
|
382
|
+
kind: "exact",
|
|
383
|
+
path: pattern,
|
|
384
|
+
symbol: null
|
|
385
|
+
},
|
|
386
|
+
field: "affectedBy",
|
|
387
|
+
owner,
|
|
388
|
+
pointer: childPointer$1(pointer, String(index))
|
|
389
|
+
});
|
|
390
|
+
};
|
|
391
|
+
/** Adds project-level or agent-level unresolved requirement references. */
|
|
392
|
+
var addUnresolvedDeclarations = (declarations, requirements, pointer, agentId) => {
|
|
393
|
+
for (const requirementId of Object.keys(requirements ?? {}).sort(compareExactStrings)) {
|
|
394
|
+
const requirement = requirements?.[requirementId];
|
|
395
|
+
if (requirement === void 0) continue;
|
|
396
|
+
const owner = createOwner("unresolved", requirementId, agentId);
|
|
397
|
+
addReferenceDeclarations(declarations, requirement.related, owner, "related", childPointer$1(childPointer$1(pointer, requirementId), "related"));
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
/** Adds exact and impact declarations owned by one tool or skill capability. */
|
|
401
|
+
var addCapabilityDeclarations = (declarations, capabilityId, capability, agentId, pointer) => {
|
|
402
|
+
const owner = createOwner(capability.kind, capabilityId, agentId);
|
|
403
|
+
addExactDeclaration(declarations, owner, "implementation", childPointer$1(pointer, "implementation"), capability.value.implementation);
|
|
404
|
+
if (capability.value.registration !== void 0) addExactDeclaration(declarations, owner, "registration", childPointer$1(pointer, "registration"), capability.value.registration);
|
|
405
|
+
if (capability.kind === "tool") for (const field of ["inputSchema", "outputSchema"]) {
|
|
406
|
+
const reference = capability.value[field];
|
|
407
|
+
if (reference !== void 0) addExactDeclaration(declarations, owner, field, childPointer$1(pointer, field), reference);
|
|
408
|
+
}
|
|
409
|
+
addAffectedByDeclarations(declarations, capability.value.affectedBy, owner, childPointer$1(pointer, "affectedBy"));
|
|
410
|
+
};
|
|
411
|
+
/** Adds all exact and impact relationships owned by one registered agent. */
|
|
412
|
+
var addAgentDeclarations = (declarations, agentId, agent) => {
|
|
413
|
+
const pointer = childPointer$1("/agents", agentId);
|
|
414
|
+
const owner = createOwner("agent", agentId, agentId);
|
|
415
|
+
const bindingsPointer = childPointer$1(pointer, "bindings");
|
|
416
|
+
for (const field of [
|
|
417
|
+
"runtimeAgent",
|
|
418
|
+
"inputSchema",
|
|
419
|
+
"outputSchema",
|
|
420
|
+
"instructionLoader"
|
|
421
|
+
]) {
|
|
422
|
+
const reference = agent.bindings?.[field];
|
|
423
|
+
if (reference !== void 0) addExactDeclaration(declarations, owner, field, childPointer$1(bindingsPointer, field), reference);
|
|
424
|
+
}
|
|
425
|
+
for (const variableId of Object.keys(agent.bindings?.variableProviders ?? {}).sort(compareExactStrings)) {
|
|
426
|
+
const reference = agent.bindings?.variableProviders?.[variableId];
|
|
427
|
+
if (reference !== void 0) addExactDeclaration(declarations, owner, "variableProvider", childPointer$1(childPointer$1(bindingsPointer, "variableProviders"), variableId), reference);
|
|
428
|
+
}
|
|
429
|
+
addAffectedByDeclarations(declarations, agent.affectedBy, owner, childPointer$1(pointer, "affectedBy"));
|
|
430
|
+
for (const capabilityId of Object.keys(agent.tools ?? {}).sort(compareExactStrings)) {
|
|
431
|
+
const tool = agent.tools?.[capabilityId];
|
|
432
|
+
if (tool !== void 0) addCapabilityDeclarations(declarations, capabilityId, {
|
|
433
|
+
kind: "tool",
|
|
434
|
+
value: tool
|
|
435
|
+
}, agentId, childPointer$1(childPointer$1(pointer, "tools"), capabilityId));
|
|
436
|
+
}
|
|
437
|
+
for (const capabilityId of Object.keys(agent.skills ?? {}).sort(compareExactStrings)) {
|
|
438
|
+
const skill = agent.skills?.[capabilityId];
|
|
439
|
+
if (skill !== void 0) addCapabilityDeclarations(declarations, capabilityId, {
|
|
440
|
+
kind: "skill",
|
|
441
|
+
value: skill
|
|
442
|
+
}, agentId, childPointer$1(childPointer$1(pointer, "skills"), capabilityId));
|
|
443
|
+
}
|
|
444
|
+
for (const [index, mirror] of (agent.mirrors ?? []).entries()) addExactDeclaration(declarations, owner, "mirrors", childPointer$1(childPointer$1(pointer, "mirrors"), String(index)), mirror);
|
|
445
|
+
addUnresolvedDeclarations(declarations, agent.unresolved, childPointer$1(pointer, "unresolved"), agentId);
|
|
446
|
+
};
|
|
447
|
+
/** Collects every version 1 declaration that can establish changed-path relevance. */
|
|
448
|
+
var collectManifestScopeDeclarations = (manifest) => {
|
|
449
|
+
const declarations = [];
|
|
450
|
+
for (const kind of ["context", "decision"]) {
|
|
451
|
+
const relationships = kind === "context" ? manifest.context : manifest.decisions;
|
|
452
|
+
for (const ownerId of Object.keys(relationships ?? {}).sort(compareExactStrings)) {
|
|
453
|
+
const relationship = relationships?.[ownerId];
|
|
454
|
+
if (relationship === void 0) continue;
|
|
455
|
+
const owner = createOwner(kind, ownerId);
|
|
456
|
+
const pointer = childPointer$1(kind === "context" ? "/context" : "/decisions", ownerId);
|
|
457
|
+
addReferenceDeclarations(declarations, relationship.bindings, owner, "bindings", childPointer$1(pointer, "bindings"));
|
|
458
|
+
addAffectedByDeclarations(declarations, relationship.affectedBy, owner, childPointer$1(pointer, "affectedBy"));
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
addUnresolvedDeclarations(declarations, manifest.unresolved, "/unresolved", null);
|
|
462
|
+
for (const agentId of Object.keys(manifest.agents ?? {}).sort(compareExactStrings)) {
|
|
463
|
+
const agent = manifest.agents?.[agentId];
|
|
464
|
+
if (agent !== void 0) addAgentDeclarations(declarations, agentId, agent);
|
|
465
|
+
}
|
|
466
|
+
return declarations.sort(compareDeclarations);
|
|
467
|
+
};
|
|
468
|
+
/** Builds exact and first-segment glob indexes once for one parsed manifest. */
|
|
469
|
+
var compileManifestScope = (manifest, limits) => {
|
|
470
|
+
const declarations = collectManifestScopeDeclarations(manifest);
|
|
471
|
+
if (declarations.length > limits.maxEntries) throw new CoreOperationException({
|
|
472
|
+
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
473
|
+
limit: "maxEntries",
|
|
474
|
+
limitMaximum: limits.maxEntries,
|
|
475
|
+
nextAction: "reduce-input-or-increase-limit",
|
|
476
|
+
observedUsage: declarations.length,
|
|
477
|
+
operation: "match-manifest-scope"
|
|
478
|
+
});
|
|
479
|
+
const exact = /* @__PURE__ */ new Map();
|
|
480
|
+
const globalGlobs = [];
|
|
481
|
+
const globsByFirstSegment = /* @__PURE__ */ new Map();
|
|
482
|
+
for (const declaration of declarations) {
|
|
483
|
+
if (declaration.declaration.kind === "exact") {
|
|
484
|
+
const existing = exact.get(declaration.declaration.path) ?? [];
|
|
485
|
+
existing.push(declaration);
|
|
486
|
+
exact.set(declaration.declaration.path, existing);
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
const segments = declaration.declaration.pattern.slice(1).split("/");
|
|
490
|
+
const compiled = {
|
|
491
|
+
declaration,
|
|
492
|
+
segments
|
|
493
|
+
};
|
|
494
|
+
const firstSegment = segments[0] ?? "";
|
|
495
|
+
if (firstSegment === "**" || firstSegment.includes("*")) globalGlobs.push(compiled);
|
|
496
|
+
else {
|
|
497
|
+
const existing = globsByFirstSegment.get(firstSegment) ?? [];
|
|
498
|
+
existing.push(compiled);
|
|
499
|
+
globsByFirstSegment.set(firstSegment, existing);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return {
|
|
503
|
+
declarations,
|
|
504
|
+
exact,
|
|
505
|
+
globalGlobs,
|
|
506
|
+
globsByFirstSegment
|
|
507
|
+
};
|
|
508
|
+
};
|
|
509
|
+
var compareMatches = (left, right) => {
|
|
510
|
+
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);
|
|
511
|
+
};
|
|
512
|
+
var createMatch = (inputPath, relationship) => ({
|
|
513
|
+
declaration: relationship.declaration,
|
|
514
|
+
field: relationship.field,
|
|
515
|
+
inputPath,
|
|
516
|
+
owner: relationship.owner,
|
|
517
|
+
pointer: relationship.pointer
|
|
518
|
+
});
|
|
519
|
+
/** Adds one match without ever allocating beyond the operation entry budget. */
|
|
520
|
+
var addMatch = (matches, inputPath, relationship, limits) => {
|
|
521
|
+
if (matches.length >= limits.maxEntries) throw new CoreOperationException({
|
|
522
|
+
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
523
|
+
limit: "maxEntries",
|
|
524
|
+
limitMaximum: limits.maxEntries,
|
|
525
|
+
nextAction: "reduce-input-or-increase-limit",
|
|
526
|
+
observedUsage: matches.length + 1,
|
|
527
|
+
operation: "match-manifest-scope"
|
|
528
|
+
});
|
|
529
|
+
matches.push(createMatch(inputPath, relationship));
|
|
530
|
+
};
|
|
531
|
+
/** Appends matches from one precompiled glob bucket without copying the bucket. */
|
|
532
|
+
var addGlobMatches = (matches, inputPath, declarations, limits) => {
|
|
533
|
+
for (const compiled of declarations) if (matchesRepositoryGlob(compiled.segments, inputPath)) addMatch(matches, inputPath, compiled.declaration, limits);
|
|
534
|
+
};
|
|
535
|
+
/** Creates the canonical digest of the sorted unique changed-path set. */
|
|
536
|
+
var calculateManifestScopeInputDigest = async (paths) => {
|
|
537
|
+
const value = paths.join("\0");
|
|
538
|
+
return calculateNormalizedTextDigest({
|
|
539
|
+
scalarLength: countUnicodeScalars$1(value),
|
|
540
|
+
utf8ByteLength: measureUtf8ByteLength(value),
|
|
541
|
+
value
|
|
542
|
+
});
|
|
543
|
+
};
|
|
544
|
+
/**
|
|
545
|
+
* Matches normalized changed paths against one valid version 1 manifest.
|
|
546
|
+
* @param manifest The parsed and validated manifest value.
|
|
547
|
+
* @param paths Sorted unique repository-logical changed paths.
|
|
548
|
+
* @param limits The immutable Core operation limits.
|
|
549
|
+
* @returns Frozen content-free matches and stable aggregate counts.
|
|
550
|
+
* @throws
|
|
551
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
552
|
+
*/
|
|
553
|
+
var matchParsedManifestScope = (manifest, paths, limits) => {
|
|
554
|
+
const compiled = compileManifestScope(manifest, limits);
|
|
555
|
+
const matches = [];
|
|
556
|
+
const matchedOwners = /* @__PURE__ */ new Set();
|
|
557
|
+
const matchedPaths = /* @__PURE__ */ new Set();
|
|
558
|
+
for (const path of paths) {
|
|
559
|
+
const firstSegment = path.slice(1).split("/", 1)[0] ?? "";
|
|
560
|
+
const exactDeclarations = compiled.exact.get(path) ?? [];
|
|
561
|
+
for (const relationship of exactDeclarations) addMatch(matches, path, relationship, limits);
|
|
562
|
+
addGlobMatches(matches, path, compiled.globalGlobs, limits);
|
|
563
|
+
addGlobMatches(matches, path, compiled.globsByFirstSegment.get(firstSegment) ?? [], limits);
|
|
564
|
+
}
|
|
565
|
+
matches.sort(compareMatches);
|
|
566
|
+
for (const match of matches) {
|
|
567
|
+
matchedOwners.add(`${match.owner.kind}\0${match.owner.agentId ?? ""}\0${match.owner.id}`);
|
|
568
|
+
matchedPaths.add(match.inputPath);
|
|
569
|
+
}
|
|
570
|
+
return freezeRecursively({
|
|
571
|
+
counts: {
|
|
572
|
+
declarations: compiled.declarations.length,
|
|
573
|
+
inputPaths: paths.length,
|
|
574
|
+
matchedOwners: matchedOwners.size,
|
|
575
|
+
matchedPaths: matchedPaths.size,
|
|
576
|
+
matches: matches.length
|
|
577
|
+
},
|
|
578
|
+
matches
|
|
579
|
+
});
|
|
580
|
+
};
|
|
581
|
+
//#endregion
|
|
582
|
+
//#region src/manifest-validation/index.ts
|
|
583
|
+
var childPointer = (pointer, key) => {
|
|
584
|
+
return `${pointer}/${escapeJsonPointerSegment(key)}`;
|
|
585
|
+
};
|
|
586
|
+
var addInvalidValue = (context, pointer, range, reason, entity = null) => {
|
|
587
|
+
context.diagnostics.add({
|
|
588
|
+
code: "MOLDEA_MANIFEST_VALUE_INVALID",
|
|
589
|
+
details: { reason },
|
|
590
|
+
entity,
|
|
591
|
+
path: context.path,
|
|
592
|
+
pointer,
|
|
593
|
+
range
|
|
594
|
+
});
|
|
595
|
+
};
|
|
596
|
+
var readMapping = (node, pointer, allowedProperties, context, entity = null) => {
|
|
597
|
+
if (node.kind !== "mapping") {
|
|
598
|
+
addInvalidValue(context, pointer, node.range, "mapping-required", entity);
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
const entries = /* @__PURE__ */ new Map();
|
|
602
|
+
for (const entry of node.entries) {
|
|
603
|
+
if (entry.key.kind !== "scalar" || typeof entry.key.value !== "string") {
|
|
604
|
+
addInvalidValue(context, pointer, entry.key.range, "string-key-required", entity);
|
|
605
|
+
continue;
|
|
606
|
+
}
|
|
607
|
+
const key = entry.key.value;
|
|
608
|
+
if (allowedProperties !== null && !allowedProperties.has(key)) {
|
|
609
|
+
context.diagnostics.add({
|
|
610
|
+
code: "MOLDEA_MANIFEST_PROPERTY_UNKNOWN",
|
|
611
|
+
entity,
|
|
612
|
+
path: context.path,
|
|
613
|
+
pointer: childPointer(pointer, key),
|
|
614
|
+
range: entry.key.range
|
|
615
|
+
});
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
entries.set(key, {
|
|
619
|
+
key: entry.key,
|
|
620
|
+
value: entry.value
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
return entries;
|
|
624
|
+
};
|
|
625
|
+
var readString = (entry, pointer, context, options = {}) => {
|
|
626
|
+
if (entry === void 0) {
|
|
627
|
+
if (options.required === true) addInvalidValue(context, pointer, null, "required", options.entity ?? null);
|
|
628
|
+
return null;
|
|
629
|
+
}
|
|
630
|
+
if (entry.value.kind !== "scalar" || typeof entry.value.value !== "string") {
|
|
631
|
+
addInvalidValue(context, pointer, entry.value.range, "string-required", options.entity ?? null);
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
const value = entry.value.value;
|
|
635
|
+
if (!hasNonWhitespace(value) || options.singleLine === true && !isNonEmptySingleLine(value)) {
|
|
636
|
+
addInvalidValue(context, pointer, entry.value.range, "string-invalid", options.entity ?? null);
|
|
637
|
+
return null;
|
|
638
|
+
}
|
|
639
|
+
return value;
|
|
640
|
+
};
|
|
641
|
+
var validateStableId = (value, range, pointer, context, entity = null) => {
|
|
642
|
+
if (!isStableId(value)) {
|
|
643
|
+
context.diagnostics.add({
|
|
644
|
+
code: "MOLDEA_ID_INVALID",
|
|
645
|
+
entity,
|
|
646
|
+
path: context.path,
|
|
647
|
+
pointer,
|
|
648
|
+
range
|
|
649
|
+
});
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
652
|
+
if (isReservedId(value)) {
|
|
653
|
+
context.diagnostics.add({
|
|
654
|
+
code: "MOLDEA_ID_RESERVED",
|
|
655
|
+
entity,
|
|
656
|
+
path: context.path,
|
|
657
|
+
pointer,
|
|
658
|
+
range
|
|
659
|
+
});
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
return true;
|
|
663
|
+
};
|
|
664
|
+
var readReference = (node, pointer, context, entity = null) => {
|
|
665
|
+
const entries = readMapping(node, pointer, /* @__PURE__ */ new Set(["path", "symbol"]), context, entity);
|
|
666
|
+
if (entries === null) return null;
|
|
667
|
+
const pathEntry = entries.get("path");
|
|
668
|
+
if (pathEntry?.value.kind !== "scalar" || typeof pathEntry.value.value !== "string") {
|
|
669
|
+
context.diagnostics.add({
|
|
670
|
+
code: "MOLDEA_PATH_INVALID",
|
|
671
|
+
details: { reason: pathEntry === void 0 ? "missing" : "type" },
|
|
672
|
+
entity,
|
|
673
|
+
path: context.path,
|
|
674
|
+
pointer: childPointer(pointer, "path"),
|
|
675
|
+
range: pathEntry?.value.range ?? null
|
|
676
|
+
});
|
|
677
|
+
return null;
|
|
678
|
+
}
|
|
679
|
+
const path = parseManifestPath(pathEntry.value.value);
|
|
680
|
+
if (path === null) {
|
|
681
|
+
context.diagnostics.add({
|
|
682
|
+
code: "MOLDEA_PATH_INVALID",
|
|
683
|
+
entity,
|
|
684
|
+
path: context.path,
|
|
685
|
+
pointer: childPointer(pointer, "path"),
|
|
686
|
+
range: pathEntry.value.range
|
|
687
|
+
});
|
|
688
|
+
return null;
|
|
689
|
+
}
|
|
690
|
+
const symbolEntry = entries.get("symbol");
|
|
691
|
+
if (symbolEntry === void 0) return { path };
|
|
692
|
+
if (symbolEntry.value.kind !== "scalar" || typeof symbolEntry.value.value !== "string" || !isRepositorySymbol(symbolEntry.value.value)) {
|
|
693
|
+
context.diagnostics.add({
|
|
694
|
+
code: "MOLDEA_SYMBOL_INVALID",
|
|
695
|
+
entity,
|
|
696
|
+
path: context.path,
|
|
697
|
+
pointer: childPointer(pointer, "symbol"),
|
|
698
|
+
range: symbolEntry.value.range
|
|
699
|
+
});
|
|
700
|
+
return null;
|
|
701
|
+
}
|
|
702
|
+
if (isCanonicalMoldeaPath(path)) {
|
|
703
|
+
context.diagnostics.add({
|
|
704
|
+
code: "MOLDEA_SYMBOL_FORBIDDEN",
|
|
705
|
+
entity,
|
|
706
|
+
path: context.path,
|
|
707
|
+
pointer: childPointer(pointer, "symbol"),
|
|
708
|
+
range: symbolEntry.value.range
|
|
709
|
+
});
|
|
710
|
+
return null;
|
|
711
|
+
}
|
|
712
|
+
return {
|
|
713
|
+
path,
|
|
714
|
+
symbol: symbolEntry.value.value
|
|
715
|
+
};
|
|
716
|
+
};
|
|
717
|
+
var readReferenceList = (node, pointer, context, entity = null) => {
|
|
718
|
+
if (node.kind !== "sequence" || node.items.length === 0) {
|
|
719
|
+
addInvalidValue(context, pointer, node.range, "non-empty-sequence-required", entity);
|
|
720
|
+
return [];
|
|
721
|
+
}
|
|
722
|
+
const references = [];
|
|
723
|
+
const seen = /* @__PURE__ */ new Set();
|
|
724
|
+
node.items.forEach((item, index) => {
|
|
725
|
+
const reference = readReference(item, childPointer(pointer, String(index)), context, entity);
|
|
726
|
+
if (reference === null) return;
|
|
727
|
+
const key = `${reference.path}\0${reference.symbol ?? ""}`;
|
|
728
|
+
if (seen.has(key)) {
|
|
729
|
+
context.diagnostics.add({
|
|
730
|
+
code: "MOLDEA_PATH_DUPLICATE",
|
|
731
|
+
entity,
|
|
732
|
+
path: context.path,
|
|
733
|
+
pointer: childPointer(pointer, String(index)),
|
|
734
|
+
range: item.range
|
|
735
|
+
});
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
seen.add(key);
|
|
739
|
+
references.push(reference);
|
|
740
|
+
});
|
|
741
|
+
return sortRepositoryReferences(references);
|
|
742
|
+
};
|
|
743
|
+
var readAffectedBy = (node, pointer, context, entity = null) => {
|
|
744
|
+
if (node.kind !== "sequence" || node.items.length === 0) {
|
|
745
|
+
addInvalidValue(context, pointer, node.range, "non-empty-sequence-required", entity);
|
|
746
|
+
return [];
|
|
747
|
+
}
|
|
748
|
+
const values = [];
|
|
749
|
+
const seen = /* @__PURE__ */ new Set();
|
|
750
|
+
node.items.forEach((item, index) => {
|
|
751
|
+
const itemPointer = childPointer(pointer, String(index));
|
|
752
|
+
if (item.kind !== "scalar" || typeof item.value !== "string") {
|
|
753
|
+
addInvalidValue(context, itemPointer, item.range, "string-required", entity);
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
const isGlob = item.value.includes("*") || hasUnsupportedGlobMetacharacter(item.value);
|
|
757
|
+
if (!(isGlob ? isSimpleGlob(item.value) : parseManifestPath(item.value) !== null)) {
|
|
758
|
+
context.diagnostics.add({
|
|
759
|
+
code: isGlob ? "MOLDEA_GLOB_INVALID" : "MOLDEA_PATH_INVALID",
|
|
760
|
+
entity,
|
|
761
|
+
path: context.path,
|
|
762
|
+
pointer: itemPointer,
|
|
763
|
+
range: item.range
|
|
764
|
+
});
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
if (seen.has(item.value)) {
|
|
768
|
+
context.diagnostics.add({
|
|
769
|
+
code: isGlob ? "MOLDEA_PATTERN_DUPLICATE" : "MOLDEA_PATH_DUPLICATE",
|
|
770
|
+
entity,
|
|
771
|
+
path: context.path,
|
|
772
|
+
pointer: itemPointer,
|
|
773
|
+
range: item.range
|
|
774
|
+
});
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
seen.add(item.value);
|
|
778
|
+
values.push(item.value);
|
|
779
|
+
});
|
|
780
|
+
return values.sort(compareExactStrings);
|
|
781
|
+
};
|
|
782
|
+
var readRelationship = (node, pointer, context) => {
|
|
783
|
+
const entries = readMapping(node, pointer, /* @__PURE__ */ new Set(["affectedBy", "bindings"]), context);
|
|
784
|
+
if (entries === null) return null;
|
|
785
|
+
const bindingsEntry = entries.get("bindings");
|
|
786
|
+
const affectedByEntry = entries.get("affectedBy");
|
|
787
|
+
if (bindingsEntry === void 0 && affectedByEntry === void 0) context.diagnostics.add({
|
|
788
|
+
code: "MOLDEA_CONTEXT_RELATIONSHIP_EMPTY",
|
|
789
|
+
path: context.path,
|
|
790
|
+
pointer,
|
|
791
|
+
range: node.range
|
|
792
|
+
});
|
|
793
|
+
return {
|
|
794
|
+
...bindingsEntry === void 0 ? {} : { bindings: readReferenceList(bindingsEntry.value, childPointer(pointer, "bindings"), context) },
|
|
795
|
+
...affectedByEntry === void 0 ? {} : { affectedBy: readAffectedBy(affectedByEntry.value, childPointer(pointer, "affectedBy"), context) }
|
|
796
|
+
};
|
|
797
|
+
};
|
|
798
|
+
var readRelationshipRecord = (node, pointer, kind, context) => {
|
|
799
|
+
const entries = readMapping(node, pointer, null, context);
|
|
800
|
+
if (entries === null) return null;
|
|
801
|
+
const normalized = [];
|
|
802
|
+
for (const [key, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
803
|
+
const path = parseManifestPath(key);
|
|
804
|
+
if (!(path !== null && (kind === "context" ? isContextPath(path, true) : isDecisionPath(path)))) {
|
|
805
|
+
context.diagnostics.add({
|
|
806
|
+
code: kind === "context" ? "MOLDEA_CONTEXT_PATH_INVALID" : "MOLDEA_DECISION_FILENAME_INVALID",
|
|
807
|
+
path: context.path,
|
|
808
|
+
pointer: childPointer(pointer, key),
|
|
809
|
+
range: entry.key.range
|
|
810
|
+
});
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
813
|
+
const relationship = readRelationship(entry.value, childPointer(pointer, key), context);
|
|
814
|
+
if (relationship !== null) normalized.push([key, relationship]);
|
|
815
|
+
}
|
|
816
|
+
return createNullPrototypeRecord(normalized);
|
|
817
|
+
};
|
|
818
|
+
var readPathList = (node, pointer, kind, context, entity) => {
|
|
819
|
+
if (node.kind !== "sequence") {
|
|
820
|
+
addInvalidValue(context, pointer, node.range, "sequence-required", entity);
|
|
821
|
+
return [];
|
|
822
|
+
}
|
|
823
|
+
const paths = [];
|
|
824
|
+
const seen = /* @__PURE__ */ new Set();
|
|
825
|
+
node.items.forEach((item, index) => {
|
|
826
|
+
const itemPointer = childPointer(pointer, String(index));
|
|
827
|
+
if (item.kind !== "scalar" || typeof item.value !== "string") {
|
|
828
|
+
addInvalidValue(context, itemPointer, item.range, "string-required", entity);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
const path = parseManifestPath(item.value);
|
|
832
|
+
if (!(path !== null && (kind === "context" ? isContextPath(path, false) : kind === "decision" ? isDecisionPath(path) : isMirrorPath(path))) || path === null) {
|
|
833
|
+
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";
|
|
834
|
+
context.diagnostics.add({
|
|
835
|
+
code,
|
|
836
|
+
entity,
|
|
837
|
+
path: context.path,
|
|
838
|
+
pointer: itemPointer,
|
|
839
|
+
range: item.range
|
|
840
|
+
});
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
if (seen.has(path)) {
|
|
844
|
+
context.diagnostics.add({
|
|
845
|
+
code: kind === "mirror" ? "MOLDEA_MIRROR_PATH_DUPLICATE" : "MOLDEA_PATH_DUPLICATE",
|
|
846
|
+
entity,
|
|
847
|
+
path: context.path,
|
|
848
|
+
pointer: itemPointer,
|
|
849
|
+
range: item.range
|
|
850
|
+
});
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
if (kind === "mirror" && context.mirrorPaths.has(path)) {
|
|
854
|
+
context.diagnostics.add({
|
|
855
|
+
code: "MOLDEA_MIRROR_PATH_DUPLICATE",
|
|
856
|
+
entity,
|
|
857
|
+
path: context.path,
|
|
858
|
+
pointer: itemPointer,
|
|
859
|
+
range: item.range
|
|
860
|
+
});
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
seen.add(path);
|
|
864
|
+
if (kind === "mirror") context.mirrorPaths.add(path);
|
|
865
|
+
paths.push(path);
|
|
866
|
+
});
|
|
867
|
+
return paths.sort(compareExactStrings);
|
|
868
|
+
};
|
|
869
|
+
var readRuntime = (node, pointer, context, agentId) => {
|
|
870
|
+
const entity = { agentId };
|
|
871
|
+
const entries = readMapping(node, pointer, /* @__PURE__ */ new Set(["guidance", "id"]), context, entity);
|
|
872
|
+
if (entries === null) return null;
|
|
873
|
+
const idEntry = entries.get("id");
|
|
874
|
+
if (idEntry?.value.kind !== "scalar" || typeof idEntry.value.value !== "string") {
|
|
875
|
+
context.diagnostics.add({
|
|
876
|
+
code: "MOLDEA_RUNTIME_ID_INVALID",
|
|
877
|
+
entity,
|
|
878
|
+
path: context.path,
|
|
879
|
+
pointer: childPointer(pointer, "id"),
|
|
880
|
+
range: idEntry?.value.range ?? null
|
|
881
|
+
});
|
|
882
|
+
return null;
|
|
883
|
+
}
|
|
884
|
+
const id = idEntry.value.value;
|
|
885
|
+
if (!isStableId(id) || isReservedId(id) || !RECOGNIZED_RUNTIME_IDS.includes(id)) context.diagnostics.add({
|
|
886
|
+
code: "MOLDEA_RUNTIME_ID_INVALID",
|
|
887
|
+
entity,
|
|
888
|
+
path: context.path,
|
|
889
|
+
pointer: childPointer(pointer, "id"),
|
|
890
|
+
range: idEntry.value.range
|
|
891
|
+
});
|
|
892
|
+
const guidanceEntry = entries.get("guidance");
|
|
893
|
+
let guidance = null;
|
|
894
|
+
if (guidanceEntry !== void 0) {
|
|
895
|
+
if (guidanceEntry.value.kind === "scalar" && typeof guidanceEntry.value.value === "string") {
|
|
896
|
+
const candidate = parseManifestPath(guidanceEntry.value.value);
|
|
897
|
+
if (candidate !== null && isRuntimeGuidancePath(candidate)) guidance = candidate;
|
|
898
|
+
else context.diagnostics.add({
|
|
899
|
+
code: "MOLDEA_PATH_INVALID",
|
|
900
|
+
details: { reason: "runtime-guidance" },
|
|
901
|
+
entity,
|
|
902
|
+
path: context.path,
|
|
903
|
+
pointer: childPointer(pointer, "guidance"),
|
|
904
|
+
range: guidanceEntry.value.range
|
|
905
|
+
});
|
|
906
|
+
} else context.diagnostics.add({
|
|
907
|
+
code: "MOLDEA_PATH_INVALID",
|
|
908
|
+
details: { reason: "runtime-guidance" },
|
|
909
|
+
entity,
|
|
910
|
+
path: context.path,
|
|
911
|
+
pointer: childPointer(pointer, "guidance"),
|
|
912
|
+
range: guidanceEntry.value.range
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
return {
|
|
916
|
+
id,
|
|
917
|
+
...guidance === null ? {} : { guidance }
|
|
918
|
+
};
|
|
919
|
+
};
|
|
920
|
+
var readVariables = (node, pointer, context, agentId) => {
|
|
921
|
+
const entries = readMapping(node, pointer, null, context, { agentId });
|
|
922
|
+
if (entries === null) return null;
|
|
923
|
+
const normalized = [];
|
|
924
|
+
for (const [variableId, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
925
|
+
const entity = {
|
|
926
|
+
agentId,
|
|
927
|
+
variableId
|
|
928
|
+
};
|
|
929
|
+
if (!isVariableId(variableId)) context.diagnostics.add({
|
|
930
|
+
code: "MOLDEA_VARIABLE_ID_INVALID",
|
|
931
|
+
entity,
|
|
932
|
+
path: context.path,
|
|
933
|
+
pointer: childPointer(pointer, variableId),
|
|
934
|
+
range: entry.key.range
|
|
935
|
+
});
|
|
936
|
+
const variablePointer = childPointer(pointer, variableId);
|
|
937
|
+
const variableEntries = readMapping(entry.value, variablePointer, /* @__PURE__ */ new Set(["description"]), context, entity);
|
|
938
|
+
if (variableEntries === null) continue;
|
|
939
|
+
const description = readString(variableEntries.get("description"), childPointer(variablePointer, "description"), context, {
|
|
940
|
+
entity,
|
|
941
|
+
required: true
|
|
942
|
+
});
|
|
943
|
+
if (description !== null) normalized.push([variableId, { description }]);
|
|
944
|
+
}
|
|
945
|
+
return createNullPrototypeRecord(normalized);
|
|
946
|
+
};
|
|
947
|
+
var readBindings = (node, pointer, context, agentId, declaredVariables) => {
|
|
948
|
+
const entity = { agentId };
|
|
949
|
+
const entries = readMapping(node, pointer, /* @__PURE__ */ new Set([
|
|
950
|
+
"inputSchema",
|
|
951
|
+
"instructionLoader",
|
|
952
|
+
"outputSchema",
|
|
953
|
+
"runtimeAgent",
|
|
954
|
+
"variableProviders"
|
|
955
|
+
]), context, entity);
|
|
956
|
+
if (entries === null) return null;
|
|
957
|
+
const referenceProperty = (key) => {
|
|
958
|
+
const entry = entries.get(key);
|
|
959
|
+
return entry === void 0 ? null : readReference(entry.value, childPointer(pointer, key), context, entity);
|
|
960
|
+
};
|
|
961
|
+
const inputSchema = referenceProperty("inputSchema");
|
|
962
|
+
const instructionLoader = referenceProperty("instructionLoader");
|
|
963
|
+
const outputSchema = referenceProperty("outputSchema");
|
|
964
|
+
const runtimeAgent = referenceProperty("runtimeAgent");
|
|
965
|
+
const providersEntry = entries.get("variableProviders");
|
|
966
|
+
let variableProviders = null;
|
|
967
|
+
if (providersEntry !== void 0) {
|
|
968
|
+
const providers = readMapping(providersEntry.value, childPointer(pointer, "variableProviders"), null, context, entity);
|
|
969
|
+
if (providers !== null) {
|
|
970
|
+
const normalized = [];
|
|
971
|
+
for (const [variableId, providerEntry] of [...providers].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
972
|
+
const variableEntity = {
|
|
973
|
+
agentId,
|
|
974
|
+
variableId
|
|
975
|
+
};
|
|
976
|
+
const providerPointer = childPointer(childPointer(pointer, "variableProviders"), variableId);
|
|
977
|
+
if (!isVariableId(variableId)) context.diagnostics.add({
|
|
978
|
+
code: "MOLDEA_VARIABLE_ID_INVALID",
|
|
979
|
+
entity: variableEntity,
|
|
980
|
+
path: context.path,
|
|
981
|
+
pointer: providerPointer,
|
|
982
|
+
range: providerEntry.key.range
|
|
983
|
+
});
|
|
984
|
+
else if (!declaredVariables.has(variableId)) context.diagnostics.add({
|
|
985
|
+
code: "MOLDEA_VARIABLE_PROVIDER_UNDECLARED",
|
|
986
|
+
entity: variableEntity,
|
|
987
|
+
path: context.path,
|
|
988
|
+
pointer: providerPointer,
|
|
989
|
+
range: providerEntry.key.range
|
|
990
|
+
});
|
|
991
|
+
const reference = readReference(providerEntry.value, providerPointer, context, variableEntity);
|
|
992
|
+
if (reference !== null) normalized.push([variableId, reference]);
|
|
993
|
+
}
|
|
994
|
+
variableProviders = createNullPrototypeRecord(normalized);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
return {
|
|
998
|
+
...runtimeAgent === null ? {} : { runtimeAgent },
|
|
999
|
+
...inputSchema === null ? {} : { inputSchema },
|
|
1000
|
+
...outputSchema === null ? {} : { outputSchema },
|
|
1001
|
+
...instructionLoader === null ? {} : { instructionLoader },
|
|
1002
|
+
...variableProviders === null ? {} : { variableProviders }
|
|
1003
|
+
};
|
|
1004
|
+
};
|
|
1005
|
+
var readCapability = (node, pointer, context, agentId, capabilityId, kind) => {
|
|
1006
|
+
const entity = {
|
|
1007
|
+
agentId,
|
|
1008
|
+
capabilityId,
|
|
1009
|
+
capabilityKind: kind
|
|
1010
|
+
};
|
|
1011
|
+
const entries = readMapping(node, pointer, kind === "tool" ? /* @__PURE__ */ new Set([
|
|
1012
|
+
"affectedBy",
|
|
1013
|
+
"description",
|
|
1014
|
+
"implementation",
|
|
1015
|
+
"inputSchema",
|
|
1016
|
+
"name",
|
|
1017
|
+
"outputSchema",
|
|
1018
|
+
"registration"
|
|
1019
|
+
]) : /* @__PURE__ */ new Set([
|
|
1020
|
+
"affectedBy",
|
|
1021
|
+
"description",
|
|
1022
|
+
"implementation",
|
|
1023
|
+
"name",
|
|
1024
|
+
"registration"
|
|
1025
|
+
]), context, entity);
|
|
1026
|
+
if (entries === null) return null;
|
|
1027
|
+
const name = readString(entries.get("name"), childPointer(pointer, "name"), context, {
|
|
1028
|
+
entity,
|
|
1029
|
+
required: true,
|
|
1030
|
+
singleLine: true
|
|
1031
|
+
});
|
|
1032
|
+
const descriptionEntry = entries.get("description");
|
|
1033
|
+
let description = null;
|
|
1034
|
+
if (descriptionEntry === void 0) context.diagnostics.add({
|
|
1035
|
+
code: "MOLDEA_CAPABILITY_DESCRIPTION_MISSING",
|
|
1036
|
+
entity,
|
|
1037
|
+
path: context.path,
|
|
1038
|
+
pointer: childPointer(pointer, "description")
|
|
1039
|
+
});
|
|
1040
|
+
else if (descriptionEntry.value.kind !== "scalar" || typeof descriptionEntry.value.value !== "string" || !isCapabilityDescription(descriptionEntry.value.value)) context.diagnostics.add({
|
|
1041
|
+
code: "MOLDEA_CAPABILITY_DESCRIPTION_INVALID",
|
|
1042
|
+
entity,
|
|
1043
|
+
path: context.path,
|
|
1044
|
+
pointer: childPointer(pointer, "description"),
|
|
1045
|
+
range: descriptionEntry.value.range
|
|
1046
|
+
});
|
|
1047
|
+
else description = descriptionEntry.value.value;
|
|
1048
|
+
const implementationEntry = entries.get("implementation");
|
|
1049
|
+
let implementation = null;
|
|
1050
|
+
if (implementationEntry === void 0) context.diagnostics.add({
|
|
1051
|
+
code: kind === "tool" ? "MOLDEA_TOOL_IMPLEMENTATION_MISSING" : "MOLDEA_SKILL_IMPLEMENTATION_MISSING",
|
|
1052
|
+
entity,
|
|
1053
|
+
path: context.path,
|
|
1054
|
+
pointer: childPointer(pointer, "implementation")
|
|
1055
|
+
});
|
|
1056
|
+
else implementation = readReference(implementationEntry.value, childPointer(pointer, "implementation"), context, entity);
|
|
1057
|
+
const optionalReference = (key) => {
|
|
1058
|
+
const entry = entries.get(key);
|
|
1059
|
+
return entry === void 0 ? null : readReference(entry.value, childPointer(pointer, key), context, entity);
|
|
1060
|
+
};
|
|
1061
|
+
const registration = optionalReference("registration");
|
|
1062
|
+
const inputSchema = kind === "tool" ? optionalReference("inputSchema") : null;
|
|
1063
|
+
const outputSchema = kind === "tool" ? optionalReference("outputSchema") : null;
|
|
1064
|
+
const affectedByEntry = entries.get("affectedBy");
|
|
1065
|
+
const affectedBy = affectedByEntry === void 0 ? null : readAffectedBy(affectedByEntry.value, childPointer(pointer, "affectedBy"), context, entity);
|
|
1066
|
+
if (name === null || description === null || implementation === null) return null;
|
|
1067
|
+
return {
|
|
1068
|
+
name,
|
|
1069
|
+
description,
|
|
1070
|
+
implementation,
|
|
1071
|
+
...registration === null ? {} : { registration },
|
|
1072
|
+
...inputSchema === null ? {} : { inputSchema },
|
|
1073
|
+
...outputSchema === null ? {} : { outputSchema },
|
|
1074
|
+
...affectedBy === null ? {} : { affectedBy }
|
|
1075
|
+
};
|
|
1076
|
+
};
|
|
1077
|
+
var readCapabilities = (node, pointer, context, agentId, kind) => {
|
|
1078
|
+
const entries = readMapping(node, pointer, null, context, { agentId });
|
|
1079
|
+
if (entries === null) return null;
|
|
1080
|
+
const normalized = [];
|
|
1081
|
+
for (const [capabilityId, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
1082
|
+
const entity = {
|
|
1083
|
+
agentId,
|
|
1084
|
+
capabilityId,
|
|
1085
|
+
capabilityKind: kind
|
|
1086
|
+
};
|
|
1087
|
+
const capabilityPointer = childPointer(pointer, capabilityId);
|
|
1088
|
+
validateStableId(capabilityId, entry.key.range, capabilityPointer, context, entity);
|
|
1089
|
+
const capability = readCapability(entry.value, capabilityPointer, context, agentId, capabilityId, kind);
|
|
1090
|
+
if (capability !== null) normalized.push([capabilityId, capability]);
|
|
1091
|
+
}
|
|
1092
|
+
return createNullPrototypeRecord(normalized);
|
|
1093
|
+
};
|
|
1094
|
+
var readUnresolved = (node, pointer, context, agentId) => {
|
|
1095
|
+
const entries = readMapping(node, pointer, null, context, agentId === void 0 ? null : { agentId });
|
|
1096
|
+
if (entries === null) return null;
|
|
1097
|
+
const normalized = [];
|
|
1098
|
+
for (const [requirementId, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
1099
|
+
const entity = agentId === void 0 ? null : { agentId };
|
|
1100
|
+
const requirementPointer = childPointer(pointer, requirementId);
|
|
1101
|
+
validateStableId(requirementId, entry.key.range, requirementPointer, context, entity);
|
|
1102
|
+
const requirementEntries = readMapping(entry.value, requirementPointer, /* @__PURE__ */ new Set([
|
|
1103
|
+
"category",
|
|
1104
|
+
"description",
|
|
1105
|
+
"effect",
|
|
1106
|
+
"reference",
|
|
1107
|
+
"related",
|
|
1108
|
+
"resolution"
|
|
1109
|
+
]), context, entity);
|
|
1110
|
+
if (requirementEntries === null) continue;
|
|
1111
|
+
const category = readString(requirementEntries.get("category"), childPointer(requirementPointer, "category"), context, {
|
|
1112
|
+
...entity === null ? {} : { entity },
|
|
1113
|
+
required: true
|
|
1114
|
+
});
|
|
1115
|
+
if (category !== null && !isStableId(category)) context.diagnostics.add({
|
|
1116
|
+
code: "MOLDEA_ID_INVALID",
|
|
1117
|
+
entity,
|
|
1118
|
+
path: context.path,
|
|
1119
|
+
pointer: childPointer(requirementPointer, "category"),
|
|
1120
|
+
range: requirementEntries.get("category")?.value.range ?? null
|
|
1121
|
+
});
|
|
1122
|
+
const effectEntry = requirementEntries.get("effect");
|
|
1123
|
+
let effect = null;
|
|
1124
|
+
if (effectEntry?.value.kind === "scalar" && (effectEntry.value.value === "blocking" || effectEntry.value.value === "warning" || effectEntry.value.value === "informational")) effect = effectEntry.value.value;
|
|
1125
|
+
else addInvalidValue(context, childPointer(requirementPointer, "effect"), effectEntry?.value.range ?? null, effectEntry === void 0 ? "required" : "enum", entity);
|
|
1126
|
+
const description = readString(requirementEntries.get("description"), childPointer(requirementPointer, "description"), context, {
|
|
1127
|
+
...entity === null ? {} : { entity },
|
|
1128
|
+
required: true
|
|
1129
|
+
});
|
|
1130
|
+
const resolution = readString(requirementEntries.get("resolution"), childPointer(requirementPointer, "resolution"), context, {
|
|
1131
|
+
...entity === null ? {} : { entity },
|
|
1132
|
+
required: true
|
|
1133
|
+
});
|
|
1134
|
+
const relatedEntry = requirementEntries.get("related");
|
|
1135
|
+
const related = relatedEntry === void 0 ? null : readReferenceList(relatedEntry.value, childPointer(requirementPointer, "related"), context, entity);
|
|
1136
|
+
const reference = readString(requirementEntries.get("reference"), childPointer(requirementPointer, "reference"), context, {
|
|
1137
|
+
...entity === null ? {} : { entity },
|
|
1138
|
+
singleLine: true
|
|
1139
|
+
});
|
|
1140
|
+
if (category !== null && effect !== null && description !== null && resolution !== null) normalized.push([requirementId, {
|
|
1141
|
+
category,
|
|
1142
|
+
effect,
|
|
1143
|
+
description,
|
|
1144
|
+
resolution,
|
|
1145
|
+
...related === null ? {} : { related },
|
|
1146
|
+
...reference === null ? {} : { reference }
|
|
1147
|
+
}]);
|
|
1148
|
+
}
|
|
1149
|
+
return createNullPrototypeRecord(normalized);
|
|
1150
|
+
};
|
|
1151
|
+
var findMappingProperty = (node, property) => {
|
|
1152
|
+
if (node.kind !== "mapping") return null;
|
|
1153
|
+
for (const entry of node.entries) if (entry.key.kind === "scalar" && entry.key.value === property) return entry.value;
|
|
1154
|
+
return null;
|
|
1155
|
+
};
|
|
1156
|
+
/**
|
|
1157
|
+
* Detects a supported repository-format version without treating the remaining manifest as valid.
|
|
1158
|
+
* @param node The trustworthy strict-YAML manifest root.
|
|
1159
|
+
* @returns The supported parsed version when its declaration is independently unambiguous.
|
|
1160
|
+
*/
|
|
1161
|
+
var detectSupportedManifestVersion = (node) => {
|
|
1162
|
+
if (node.kind !== "mapping") return null;
|
|
1163
|
+
const versionNode = findMappingProperty(node, "version");
|
|
1164
|
+
return versionNode?.kind === "scalar" && versionNode.value === 1n ? 1 : null;
|
|
1165
|
+
};
|
|
1166
|
+
var validateAgentOwnedIdUniqueness = (node, pointer, context, agentId) => {
|
|
1167
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1168
|
+
for (const property of [
|
|
1169
|
+
"tools",
|
|
1170
|
+
"skills",
|
|
1171
|
+
"unresolved"
|
|
1172
|
+
]) {
|
|
1173
|
+
const record = findMappingProperty(node, property);
|
|
1174
|
+
if (record?.kind !== "mapping") continue;
|
|
1175
|
+
for (const entry of record.entries) {
|
|
1176
|
+
if (entry.key.kind !== "scalar" || typeof entry.key.value !== "string") continue;
|
|
1177
|
+
if (seen.has(entry.key.value)) context.diagnostics.add({
|
|
1178
|
+
code: "MOLDEA_ID_DUPLICATE",
|
|
1179
|
+
entity: { agentId },
|
|
1180
|
+
path: context.path,
|
|
1181
|
+
pointer: childPointer(childPointer(pointer, property), entry.key.value),
|
|
1182
|
+
range: entry.key.range
|
|
1183
|
+
});
|
|
1184
|
+
seen.add(entry.key.value);
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
};
|
|
1188
|
+
var readAgent = (node, pointer, context, agentId) => {
|
|
1189
|
+
const entity = { agentId };
|
|
1190
|
+
const entries = readMapping(node, pointer, /* @__PURE__ */ new Set([
|
|
1191
|
+
"affectedBy",
|
|
1192
|
+
"bindings",
|
|
1193
|
+
"context",
|
|
1194
|
+
"decisions",
|
|
1195
|
+
"runtime",
|
|
1196
|
+
"mirrors",
|
|
1197
|
+
"skills",
|
|
1198
|
+
"tools",
|
|
1199
|
+
"unresolved",
|
|
1200
|
+
"variables"
|
|
1201
|
+
]), context, entity);
|
|
1202
|
+
if (entries === null) return null;
|
|
1203
|
+
validateAgentOwnedIdUniqueness(node, pointer, context, agentId);
|
|
1204
|
+
const runtimeEntry = entries.get("runtime");
|
|
1205
|
+
let runtime = null;
|
|
1206
|
+
if (runtimeEntry === void 0) addInvalidValue(context, childPointer(pointer, "runtime"), null, "required", entity);
|
|
1207
|
+
else runtime = readRuntime(runtimeEntry.value, childPointer(pointer, "runtime"), context, agentId);
|
|
1208
|
+
const variablesEntry = entries.get("variables");
|
|
1209
|
+
const variables = variablesEntry === void 0 ? null : readVariables(variablesEntry.value, childPointer(pointer, "variables"), context, agentId);
|
|
1210
|
+
const declaredVariables = new Set(Object.keys(variables ?? {}));
|
|
1211
|
+
const bindingsEntry = entries.get("bindings");
|
|
1212
|
+
const bindings = bindingsEntry === void 0 ? null : readBindings(bindingsEntry.value, childPointer(pointer, "bindings"), context, agentId, declaredVariables);
|
|
1213
|
+
const contextEntry = entries.get("context");
|
|
1214
|
+
const contextPaths = contextEntry === void 0 ? null : readPathList(contextEntry.value, childPointer(pointer, "context"), "context", context, entity);
|
|
1215
|
+
const decisionsEntry = entries.get("decisions");
|
|
1216
|
+
const decisions = decisionsEntry === void 0 ? null : readPathList(decisionsEntry.value, childPointer(pointer, "decisions"), "decision", context, entity);
|
|
1217
|
+
const toolsEntry = entries.get("tools");
|
|
1218
|
+
const tools = toolsEntry === void 0 ? null : readCapabilities(toolsEntry.value, childPointer(pointer, "tools"), context, agentId, "tool");
|
|
1219
|
+
const skillsEntry = entries.get("skills");
|
|
1220
|
+
const skills = skillsEntry === void 0 ? null : readCapabilities(skillsEntry.value, childPointer(pointer, "skills"), context, agentId, "skill");
|
|
1221
|
+
const affectedByEntry = entries.get("affectedBy");
|
|
1222
|
+
const affectedBy = affectedByEntry === void 0 ? null : readAffectedBy(affectedByEntry.value, childPointer(pointer, "affectedBy"), context, entity);
|
|
1223
|
+
const mirrorsEntry = entries.get("mirrors");
|
|
1224
|
+
const mirrors = mirrorsEntry === void 0 ? null : readPathList(mirrorsEntry.value, childPointer(pointer, "mirrors"), "mirror", context, entity);
|
|
1225
|
+
const unresolvedEntry = entries.get("unresolved");
|
|
1226
|
+
const unresolved = unresolvedEntry === void 0 ? null : readUnresolved(unresolvedEntry.value, childPointer(pointer, "unresolved"), context, agentId);
|
|
1227
|
+
if (runtime === null) return null;
|
|
1228
|
+
return {
|
|
1229
|
+
runtime,
|
|
1230
|
+
...contextPaths === null ? {} : { context: contextPaths },
|
|
1231
|
+
...decisions === null ? {} : { decisions },
|
|
1232
|
+
...variables === null ? {} : { variables },
|
|
1233
|
+
...bindings === null ? {} : { bindings },
|
|
1234
|
+
...tools === null ? {} : { tools },
|
|
1235
|
+
...skills === null ? {} : { skills },
|
|
1236
|
+
...affectedBy === null ? {} : { affectedBy },
|
|
1237
|
+
...mirrors === null ? {} : { mirrors },
|
|
1238
|
+
...unresolved === null ? {} : { unresolved }
|
|
1239
|
+
};
|
|
1240
|
+
};
|
|
1241
|
+
var readAgents = (node, pointer, context) => {
|
|
1242
|
+
const entries = readMapping(node, pointer, null, context);
|
|
1243
|
+
if (entries === null) return null;
|
|
1244
|
+
const normalized = [];
|
|
1245
|
+
for (const [agentId, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
|
|
1246
|
+
const agentPointer = childPointer(pointer, agentId);
|
|
1247
|
+
validateStableId(agentId, entry.key.range, agentPointer, context, { agentId });
|
|
1248
|
+
const agent = readAgent(entry.value, agentPointer, context, agentId);
|
|
1249
|
+
if (agent !== null) normalized.push([agentId, agent]);
|
|
1250
|
+
}
|
|
1251
|
+
return createNullPrototypeRecord(normalized);
|
|
1252
|
+
};
|
|
1253
|
+
/**
|
|
1254
|
+
* Validates the closed warning-acceptance contract with field-specific diagnostics.
|
|
1255
|
+
* @returns Valid acceptance entries; diagnostics invalidate the complete manifest on any bad entry.
|
|
1256
|
+
* @throws
|
|
1257
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1258
|
+
*/
|
|
1259
|
+
var readAcceptedWarnings = (node, context) => {
|
|
1260
|
+
const report = (entry, field, range, reason) => {
|
|
1261
|
+
context.diagnostics.add({
|
|
1262
|
+
code: "MOLDEA_MANIFEST_VALUE_INVALID",
|
|
1263
|
+
path: context.path,
|
|
1264
|
+
pointer: entry === null ? "/acceptedWarnings" : `/acceptedWarnings/${entry}/${escapeJsonPointerSegment(field)}`,
|
|
1265
|
+
range,
|
|
1266
|
+
details: {
|
|
1267
|
+
entry,
|
|
1268
|
+
field,
|
|
1269
|
+
reason
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
};
|
|
1273
|
+
if (node.kind !== "sequence") {
|
|
1274
|
+
report(null, "acceptedWarnings", node.range, "sequence-required");
|
|
1275
|
+
return null;
|
|
1276
|
+
}
|
|
1277
|
+
if (node.items.length > context.limits.maxAcceptedWarnings) throw new CoreOperationException({
|
|
1278
|
+
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
1279
|
+
operation: context.operation,
|
|
1280
|
+
limit: "maxAcceptedWarnings",
|
|
1281
|
+
limitMaximum: context.limits.maxAcceptedWarnings,
|
|
1282
|
+
observedUsage: node.items.length,
|
|
1283
|
+
nextAction: "reduce-input-or-increase-limit"
|
|
1284
|
+
});
|
|
1285
|
+
const accepted = [];
|
|
1286
|
+
const identities = /* @__PURE__ */ new Set();
|
|
1287
|
+
for (const [index, item] of node.items.entries()) {
|
|
1288
|
+
if (item.kind !== "mapping") {
|
|
1289
|
+
report(index, "entry", item.range, "mapping-required");
|
|
1290
|
+
continue;
|
|
1291
|
+
}
|
|
1292
|
+
const fields = /* @__PURE__ */ new Map();
|
|
1293
|
+
let isValid = true;
|
|
1294
|
+
for (const entry of item.entries) if (entry.key.kind !== "scalar" || typeof entry.key.value !== "string" || ![
|
|
1295
|
+
"code",
|
|
1296
|
+
"subject",
|
|
1297
|
+
"qualifier",
|
|
1298
|
+
"reason"
|
|
1299
|
+
].includes(entry.key.value)) {
|
|
1300
|
+
report(index, entry.key.kind === "scalar" && typeof entry.key.value === "string" ? entry.key.value : "key", entry.key.range, "unknown-field");
|
|
1301
|
+
isValid = false;
|
|
1302
|
+
} else fields.set(entry.key.value, entry.value);
|
|
1303
|
+
const scalar = (field) => {
|
|
1304
|
+
const value = fields.get(field);
|
|
1305
|
+
if (value?.kind !== "scalar" || typeof value.value !== "string" || !hasNonWhitespace(value.value)) {
|
|
1306
|
+
report(index, field, value?.range ?? item.range, value === void 0 ? "required" : "non-empty-string-required");
|
|
1307
|
+
isValid = false;
|
|
1308
|
+
return null;
|
|
1309
|
+
}
|
|
1310
|
+
return value.value;
|
|
1311
|
+
};
|
|
1312
|
+
const code = scalar("code");
|
|
1313
|
+
const subjectText = scalar("subject");
|
|
1314
|
+
const reason = scalar("reason");
|
|
1315
|
+
const subject = subjectText === null ? null : parseManifestPath(subjectText);
|
|
1316
|
+
const qualifierNode = fields.get("qualifier");
|
|
1317
|
+
let qualifier = null;
|
|
1318
|
+
if (qualifierNode !== void 0 && !(qualifierNode.kind === "scalar" && qualifierNode.value === null)) {
|
|
1319
|
+
qualifier = scalar("qualifier");
|
|
1320
|
+
if (qualifier !== null && !isNonEmptySingleLine(qualifier)) {
|
|
1321
|
+
report(index, "qualifier", qualifierNode.range, "single-line-required");
|
|
1322
|
+
isValid = false;
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
const acceptedCode = ACCEPTABLE_WARNING_CODES.find((candidate) => candidate === code);
|
|
1326
|
+
if (code !== null && acceptedCode === void 0) {
|
|
1327
|
+
report(index, "code", fields.get("code").range, "code-not-acceptable");
|
|
1328
|
+
isValid = false;
|
|
1329
|
+
}
|
|
1330
|
+
if (subjectText !== null && subject === null) {
|
|
1331
|
+
report(index, "subject", fields.get("subject").range, "repository-path-required");
|
|
1332
|
+
isValid = false;
|
|
1333
|
+
}
|
|
1334
|
+
if (reason !== null && countUnicodeScalars$1(reason) > 256) {
|
|
1335
|
+
report(index, "reason", fields.get("reason").range, "maximum-256-characters");
|
|
1336
|
+
isValid = false;
|
|
1337
|
+
}
|
|
1338
|
+
if (!isValid || acceptedCode === void 0 || subject === null || reason === null) continue;
|
|
1339
|
+
const identity = JSON.stringify([
|
|
1340
|
+
acceptedCode,
|
|
1341
|
+
subject,
|
|
1342
|
+
qualifier
|
|
1343
|
+
]);
|
|
1344
|
+
if (identities.has(identity)) {
|
|
1345
|
+
report(index, "code", fields.get("code").range, "duplicate-identity");
|
|
1346
|
+
continue;
|
|
1347
|
+
}
|
|
1348
|
+
identities.add(identity);
|
|
1349
|
+
accepted.push({
|
|
1350
|
+
code: acceptedCode,
|
|
1351
|
+
subject,
|
|
1352
|
+
...qualifierNode === void 0 ? {} : { qualifier },
|
|
1353
|
+
reason
|
|
1354
|
+
});
|
|
1355
|
+
}
|
|
1356
|
+
return accepted;
|
|
1357
|
+
};
|
|
1358
|
+
/**
|
|
1359
|
+
* Validates and normalizes a strict YAML document as a version 1 moldea manifest.
|
|
1360
|
+
* @param node The parser-neutral YAML root node.
|
|
1361
|
+
* @param path The canonical or caller-supplied logical manifest path.
|
|
1362
|
+
* @param diagnostics The operation diagnostic collector.
|
|
1363
|
+
* @param limits The immutable operation limits, including the acceptance-list bound.
|
|
1364
|
+
* @param operation The public operation receiving resource failures.
|
|
1365
|
+
* @returns The normalized manifest when its supported version can be interpreted.
|
|
1366
|
+
* @throws
|
|
1367
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1368
|
+
*/
|
|
1369
|
+
var validateManifest = (node, path, diagnostics, limits, operation) => {
|
|
1370
|
+
const context = {
|
|
1371
|
+
diagnostics,
|
|
1372
|
+
operation,
|
|
1373
|
+
limits,
|
|
1374
|
+
mirrorPaths: /* @__PURE__ */ new Set(),
|
|
1375
|
+
path
|
|
1376
|
+
};
|
|
1377
|
+
if (node.kind !== "mapping") {
|
|
1378
|
+
diagnostics.add({
|
|
1379
|
+
code: "MOLDEA_MANIFEST_ROOT_INVALID",
|
|
1380
|
+
path,
|
|
1381
|
+
range: node.range
|
|
1382
|
+
});
|
|
1383
|
+
return null;
|
|
1384
|
+
}
|
|
1385
|
+
const versionNode = findMappingProperty(node, "version");
|
|
1386
|
+
if (versionNode === null) {
|
|
1387
|
+
diagnostics.add({
|
|
1388
|
+
code: "MOLDEA_MANIFEST_VERSION_MISSING",
|
|
1389
|
+
path,
|
|
1390
|
+
pointer: "/version"
|
|
1391
|
+
});
|
|
1392
|
+
return null;
|
|
1393
|
+
}
|
|
1394
|
+
if (!(versionNode.kind === "scalar" && typeof versionNode.value === "bigint") || versionNode.kind !== "scalar" || versionNode.value <= 0n) {
|
|
1395
|
+
diagnostics.add({
|
|
1396
|
+
code: "MOLDEA_MANIFEST_VERSION_INVALID",
|
|
1397
|
+
path,
|
|
1398
|
+
pointer: "/version",
|
|
1399
|
+
range: versionNode.range
|
|
1400
|
+
});
|
|
1401
|
+
return null;
|
|
1402
|
+
}
|
|
1403
|
+
if (versionNode.value !== 1n) {
|
|
1404
|
+
diagnostics.add({
|
|
1405
|
+
code: "MOLDEA_MANIFEST_VERSION_UNSUPPORTED",
|
|
1406
|
+
path,
|
|
1407
|
+
pointer: "/version",
|
|
1408
|
+
range: versionNode.range
|
|
1409
|
+
});
|
|
1410
|
+
return null;
|
|
1411
|
+
}
|
|
1412
|
+
const entries = readMapping(node, "", /* @__PURE__ */ new Set([
|
|
1413
|
+
"acceptedWarnings",
|
|
1414
|
+
"agents",
|
|
1415
|
+
"context",
|
|
1416
|
+
"decisions",
|
|
1417
|
+
"unresolved",
|
|
1418
|
+
"version"
|
|
1419
|
+
]), context);
|
|
1420
|
+
if (entries === null) return null;
|
|
1421
|
+
const acceptedWarningsEntry = entries.get("acceptedWarnings");
|
|
1422
|
+
const acceptedWarnings = acceptedWarningsEntry === void 0 ? null : readAcceptedWarnings(acceptedWarningsEntry.value, context);
|
|
1423
|
+
const contextEntry = entries.get("context");
|
|
1424
|
+
const contextRelationships = contextEntry === void 0 ? null : readRelationshipRecord(contextEntry.value, "/context", "context", context);
|
|
1425
|
+
const decisionsEntry = entries.get("decisions");
|
|
1426
|
+
const decisionRelationships = decisionsEntry === void 0 ? null : readRelationshipRecord(decisionsEntry.value, "/decisions", "decision", context);
|
|
1427
|
+
const unresolvedEntry = entries.get("unresolved");
|
|
1428
|
+
const unresolved = unresolvedEntry === void 0 ? null : readUnresolved(unresolvedEntry.value, "/unresolved", context);
|
|
1429
|
+
const agentsEntry = entries.get("agents");
|
|
1430
|
+
const agents = agentsEntry === void 0 ? null : readAgents(agentsEntry.value, "/agents", context);
|
|
1431
|
+
return {
|
|
1432
|
+
version: 1,
|
|
1433
|
+
...acceptedWarnings === null ? {} : { acceptedWarnings },
|
|
1434
|
+
...contextRelationships === null ? {} : { context: contextRelationships },
|
|
1435
|
+
...decisionRelationships === null ? {} : { decisions: decisionRelationships },
|
|
1436
|
+
...unresolved === null ? {} : { unresolved },
|
|
1437
|
+
...agents === null ? {} : { agents }
|
|
1438
|
+
};
|
|
1439
|
+
};
|
|
1440
|
+
//#endregion
|
|
1441
|
+
//#region src/source-location/index.ts
|
|
1442
|
+
var findLineIndex = (lineStarts, offset) => {
|
|
1443
|
+
let lower = 0;
|
|
1444
|
+
let upper = lineStarts.length - 1;
|
|
1445
|
+
while (lower < upper) {
|
|
1446
|
+
const middle = Math.ceil((lower + upper) / 2);
|
|
1447
|
+
if ((lineStarts[middle] ?? 0) <= offset) lower = middle;
|
|
1448
|
+
else upper = middle - 1;
|
|
1449
|
+
}
|
|
1450
|
+
return lower;
|
|
1451
|
+
};
|
|
1452
|
+
/**
|
|
1453
|
+
* Creates an efficient UTF-16-offset to Unicode-scalar source locator.
|
|
1454
|
+
* @param value The already-normalized valid Unicode scalar text.
|
|
1455
|
+
* @returns A locator producing one-based lines and columns with zero-based scalar offsets.
|
|
1456
|
+
*/
|
|
1457
|
+
var createSourceLocator = (value) => {
|
|
1458
|
+
const scalarOffsets = new Uint32Array(value.length + 1);
|
|
1459
|
+
const lineStarts = [0];
|
|
1460
|
+
let scalarOffset = 0;
|
|
1461
|
+
for (let codeUnitOffset = 0; codeUnitOffset < value.length;) {
|
|
1462
|
+
const codePoint = value.codePointAt(codeUnitOffset);
|
|
1463
|
+
const width = codePoint !== void 0 && codePoint > 65535 ? 2 : 1;
|
|
1464
|
+
scalarOffsets[codeUnitOffset] = scalarOffset;
|
|
1465
|
+
for (let interiorOffset = 1; interiorOffset < width; interiorOffset += 1) scalarOffsets[codeUnitOffset + interiorOffset] = scalarOffset;
|
|
1466
|
+
codeUnitOffset += width;
|
|
1467
|
+
scalarOffset += 1;
|
|
1468
|
+
scalarOffsets[codeUnitOffset] = scalarOffset;
|
|
1469
|
+
if (codePoint === 10) lineStarts.push(codeUnitOffset);
|
|
1470
|
+
}
|
|
1471
|
+
const locatePosition = (candidateOffset) => {
|
|
1472
|
+
const codeUnitOffset = Math.max(0, Math.min(value.length, candidateOffset));
|
|
1473
|
+
const lineIndex = findLineIndex(lineStarts, codeUnitOffset);
|
|
1474
|
+
const lineStart = lineStarts[lineIndex] ?? 0;
|
|
1475
|
+
const positionScalarOffset = scalarOffsets[codeUnitOffset] ?? 0;
|
|
1476
|
+
return {
|
|
1477
|
+
column: positionScalarOffset - (scalarOffsets[lineStart] ?? 0) + 1,
|
|
1478
|
+
line: lineIndex + 1,
|
|
1479
|
+
offset: positionScalarOffset
|
|
1480
|
+
};
|
|
1481
|
+
};
|
|
1482
|
+
return Object.freeze({ locateRange: (startOffset, endOffset) => ({
|
|
1483
|
+
end: locatePosition(endOffset),
|
|
1484
|
+
start: locatePosition(startOffset)
|
|
1485
|
+
}) });
|
|
1486
|
+
};
|
|
1487
|
+
//#endregion
|
|
1488
|
+
//#region src/yaml/index.ts
|
|
1489
|
+
var CORE_TAGS = /* @__PURE__ */ new Set([
|
|
1490
|
+
"tag:yaml.org,2002:bool",
|
|
1491
|
+
"tag:yaml.org,2002:float",
|
|
1492
|
+
"tag:yaml.org,2002:int",
|
|
1493
|
+
"tag:yaml.org,2002:map",
|
|
1494
|
+
"tag:yaml.org,2002:null",
|
|
1495
|
+
"tag:yaml.org,2002:seq",
|
|
1496
|
+
"tag:yaml.org,2002:str"
|
|
1497
|
+
]);
|
|
1498
|
+
var toRange = (range, locator) => {
|
|
1499
|
+
return locator.locateRange(range?.[0] ?? 0, range?.[1] ?? range?.[0] ?? 0);
|
|
1500
|
+
};
|
|
1501
|
+
var addUnsupportedFeature = (diagnostics, path, range, reason) => {
|
|
1502
|
+
diagnostics.add({
|
|
1503
|
+
code: "MOLDEA_YAML_FEATURE_UNSUPPORTED",
|
|
1504
|
+
details: { reason },
|
|
1505
|
+
path,
|
|
1506
|
+
range
|
|
1507
|
+
});
|
|
1508
|
+
};
|
|
1509
|
+
var isUnicodeScalarString = (value) => {
|
|
1510
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
1511
|
+
const codeUnit = value.charCodeAt(index);
|
|
1512
|
+
if (codeUnit >= 55296 && codeUnit <= 56319) {
|
|
1513
|
+
const nextCodeUnit = value.charCodeAt(index + 1);
|
|
1514
|
+
if (!(nextCodeUnit >= 56320 && nextCodeUnit <= 57343)) return false;
|
|
1515
|
+
index += 1;
|
|
1516
|
+
} else if (codeUnit >= 56320 && codeUnit <= 57343) return false;
|
|
1517
|
+
}
|
|
1518
|
+
return true;
|
|
1519
|
+
};
|
|
1520
|
+
var isCoreTagCompatible = (node) => {
|
|
1521
|
+
switch (node.tag) {
|
|
1522
|
+
case "tag:yaml.org,2002:bool": return isScalar(node) && typeof node.value === "boolean";
|
|
1523
|
+
case "tag:yaml.org,2002:float": return isScalar(node) && typeof node.value === "number";
|
|
1524
|
+
case "tag:yaml.org,2002:int": return isScalar(node) && typeof node.value === "bigint";
|
|
1525
|
+
case "tag:yaml.org,2002:map": return isMap(node);
|
|
1526
|
+
case "tag:yaml.org,2002:null": return isScalar(node) && node.value === null;
|
|
1527
|
+
case "tag:yaml.org,2002:seq": return isSeq(node);
|
|
1528
|
+
case "tag:yaml.org,2002:str": return isScalar(node) && typeof node.value === "string";
|
|
1529
|
+
default: return false;
|
|
1530
|
+
}
|
|
1531
|
+
};
|
|
1532
|
+
var convertNode = (node, path, locator, diagnostics) => {
|
|
1533
|
+
const range = toRange(node.range, locator);
|
|
1534
|
+
if (isAlias(node)) {
|
|
1535
|
+
addUnsupportedFeature(diagnostics, path, range, "alias");
|
|
1536
|
+
return null;
|
|
1537
|
+
}
|
|
1538
|
+
if ("anchor" in node && typeof node.anchor === "string") addUnsupportedFeature(diagnostics, path, range, "anchor");
|
|
1539
|
+
if (node.tag !== void 0) {
|
|
1540
|
+
if (!CORE_TAGS.has(node.tag)) {
|
|
1541
|
+
addUnsupportedFeature(diagnostics, path, range, "custom-tag");
|
|
1542
|
+
return null;
|
|
1543
|
+
}
|
|
1544
|
+
if (!isCoreTagCompatible(node)) {
|
|
1545
|
+
diagnostics.add({
|
|
1546
|
+
code: "MOLDEA_YAML_MALFORMED",
|
|
1547
|
+
details: { reason: "tag-value" },
|
|
1548
|
+
path,
|
|
1549
|
+
range
|
|
1550
|
+
});
|
|
1551
|
+
return null;
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
if (isScalar(node)) {
|
|
1555
|
+
const value = node.value;
|
|
1556
|
+
if (value !== null && typeof value !== "string" && typeof value !== "number" && typeof value !== "bigint" && typeof value !== "boolean") {
|
|
1557
|
+
diagnostics.add({
|
|
1558
|
+
code: "MOLDEA_YAML_MALFORMED",
|
|
1559
|
+
details: { reason: "scalar-type" },
|
|
1560
|
+
path,
|
|
1561
|
+
range
|
|
1562
|
+
});
|
|
1563
|
+
return null;
|
|
1564
|
+
}
|
|
1565
|
+
if (typeof value === "string" && !isUnicodeScalarString(value)) {
|
|
1566
|
+
diagnostics.add({
|
|
1567
|
+
code: "MOLDEA_YAML_MALFORMED",
|
|
1568
|
+
details: { reason: "invalid-unicode" },
|
|
1569
|
+
path,
|
|
1570
|
+
range
|
|
1571
|
+
});
|
|
1572
|
+
return null;
|
|
1573
|
+
}
|
|
1574
|
+
return {
|
|
1575
|
+
kind: "scalar",
|
|
1576
|
+
range,
|
|
1577
|
+
source: node.source,
|
|
1578
|
+
style: node.type ?? null,
|
|
1579
|
+
value
|
|
1580
|
+
};
|
|
1581
|
+
}
|
|
1582
|
+
if (isSeq(node)) {
|
|
1583
|
+
const items = [];
|
|
1584
|
+
for (const item of node.items) {
|
|
1585
|
+
if (item === null) {
|
|
1586
|
+
items.push({
|
|
1587
|
+
kind: "scalar",
|
|
1588
|
+
range,
|
|
1589
|
+
source: "",
|
|
1590
|
+
style: null,
|
|
1591
|
+
value: null
|
|
1592
|
+
});
|
|
1593
|
+
continue;
|
|
1594
|
+
}
|
|
1595
|
+
const converted = convertNode(item, path, locator, diagnostics);
|
|
1596
|
+
if (converted !== null) items.push(converted);
|
|
1597
|
+
}
|
|
1598
|
+
return {
|
|
1599
|
+
items,
|
|
1600
|
+
kind: "sequence",
|
|
1601
|
+
range
|
|
1602
|
+
};
|
|
1603
|
+
}
|
|
1604
|
+
if (isMap(node)) {
|
|
1605
|
+
const entries = [];
|
|
1606
|
+
for (const pair of node.items) {
|
|
1607
|
+
const key = convertNode(pair.key, path, locator, diagnostics);
|
|
1608
|
+
const value = pair.value === null ? {
|
|
1609
|
+
kind: "scalar",
|
|
1610
|
+
range: key?.range ?? range,
|
|
1611
|
+
source: "",
|
|
1612
|
+
style: null,
|
|
1613
|
+
value: null
|
|
1614
|
+
} : convertNode(pair.value, path, locator, diagnostics);
|
|
1615
|
+
if (key?.kind === "scalar" && key.value === "<<" && key.style === "PLAIN") addUnsupportedFeature(diagnostics, path, key.range, "merge-key");
|
|
1616
|
+
if (key !== null && value !== null) entries.push({
|
|
1617
|
+
key,
|
|
1618
|
+
value
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
return {
|
|
1622
|
+
entries,
|
|
1623
|
+
kind: "mapping",
|
|
1624
|
+
range
|
|
1625
|
+
};
|
|
1626
|
+
}
|
|
1627
|
+
diagnostics.add({
|
|
1628
|
+
code: "MOLDEA_YAML_MALFORMED",
|
|
1629
|
+
details: { reason: "node-type" },
|
|
1630
|
+
path,
|
|
1631
|
+
range
|
|
1632
|
+
});
|
|
1633
|
+
return null;
|
|
1634
|
+
};
|
|
1635
|
+
var addParserDiagnostic = (code, start, end, path, locator, diagnostics) => {
|
|
1636
|
+
if (code === "BAD_DIRECTIVE") return;
|
|
1637
|
+
if (code === "DUPLICATE_KEY") {
|
|
1638
|
+
diagnostics.add({
|
|
1639
|
+
code: "MOLDEA_YAML_DUPLICATE_KEY",
|
|
1640
|
+
path,
|
|
1641
|
+
range: locator.locateRange(start, end)
|
|
1642
|
+
});
|
|
1643
|
+
return;
|
|
1644
|
+
}
|
|
1645
|
+
if (code === "TAG_RESOLVE_FAILED") return;
|
|
1646
|
+
diagnostics.add({
|
|
1647
|
+
code: "MOLDEA_YAML_MALFORMED",
|
|
1648
|
+
details: { reason: code === "RESOURCE_EXHAUSTION" ? "resource-exhaustion" : "syntax" },
|
|
1649
|
+
path,
|
|
1650
|
+
range: locator.locateRange(start, end)
|
|
1651
|
+
});
|
|
1652
|
+
};
|
|
1653
|
+
/**
|
|
1654
|
+
* Parses one normalized YAML 1.2 Core Schema document into parser-neutral nodes.
|
|
1655
|
+
* @param value The normalized manifest text.
|
|
1656
|
+
* @param path The logical source path used by diagnostics.
|
|
1657
|
+
* @param locator The scalar-aware source locator for the normalized text.
|
|
1658
|
+
* @param diagnostics The operation diagnostic collector.
|
|
1659
|
+
* @returns The private parsed tree only when the YAML substrate is trustworthy.
|
|
1660
|
+
*/
|
|
1661
|
+
var parseStrictYaml = (value, path, locator, diagnostics) => {
|
|
1662
|
+
const initialDiagnosticCount = diagnostics.size;
|
|
1663
|
+
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");
|
|
1664
|
+
const documents = parseAllDocuments(value, {
|
|
1665
|
+
intAsBigInt: true,
|
|
1666
|
+
keepSourceTokens: true,
|
|
1667
|
+
logLevel: "silent",
|
|
1668
|
+
merge: false,
|
|
1669
|
+
prettyErrors: false,
|
|
1670
|
+
resolveKnownTags: false,
|
|
1671
|
+
schema: "core",
|
|
1672
|
+
strict: true,
|
|
1673
|
+
uniqueKeys: true,
|
|
1674
|
+
version: "1.2"
|
|
1675
|
+
});
|
|
1676
|
+
if (documents.length > 1) {
|
|
1677
|
+
const range = documents[1]?.range;
|
|
1678
|
+
diagnostics.add({
|
|
1679
|
+
code: "MOLDEA_YAML_MULTIPLE_DOCUMENTS",
|
|
1680
|
+
path,
|
|
1681
|
+
range: locator.locateRange(range?.[0] ?? 0, range?.[0] ?? 0)
|
|
1682
|
+
});
|
|
1683
|
+
}
|
|
1684
|
+
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);
|
|
1685
|
+
if (documents.length > 1 || diagnostics.size > initialDiagnosticCount) return {
|
|
1686
|
+
valid: false,
|
|
1687
|
+
value: null
|
|
1688
|
+
};
|
|
1689
|
+
const document = documents[0];
|
|
1690
|
+
if (document === void 0 || document.contents === null) return {
|
|
1691
|
+
valid: true,
|
|
1692
|
+
value: {
|
|
1693
|
+
kind: "scalar",
|
|
1694
|
+
range: locator.locateRange(0, 0),
|
|
1695
|
+
source: "",
|
|
1696
|
+
style: null,
|
|
1697
|
+
value: null
|
|
1698
|
+
}
|
|
1699
|
+
};
|
|
1700
|
+
const parsedValue = convertNode(document.contents, path, locator, diagnostics);
|
|
1701
|
+
return {
|
|
1702
|
+
valid: parsedValue !== null && diagnostics.size === initialDiagnosticCount,
|
|
1703
|
+
value: diagnostics.size === initialDiagnosticCount ? parsedValue : null
|
|
1704
|
+
};
|
|
1705
|
+
};
|
|
1706
|
+
//#endregion
|
|
1707
|
+
//#region src/manifest/index.ts
|
|
1708
|
+
/**
|
|
1709
|
+
* Inspects one complete manifest while retaining an independently trustworthy supported version.
|
|
1710
|
+
* @param input The canonical logical path and exact manifest text or bytes.
|
|
1711
|
+
* @param options The immutable Core limit snapshot.
|
|
1712
|
+
* @param operation The owning public or repository-level operation for typed failures.
|
|
1713
|
+
* @returns Frozen inspection state with all-or-nothing manifest assets and values.
|
|
1714
|
+
* @throws
|
|
1715
|
+
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
1716
|
+
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
1717
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1718
|
+
*/
|
|
1719
|
+
var inspectManifestDocument = async (input, options, operation = "parse-manifest") => {
|
|
1720
|
+
options = createCoreOperationOptionsSnapshot(options);
|
|
1721
|
+
const normalized = normalizeTextDocument(input, options.limits, operation, "maxManifestBytes");
|
|
1722
|
+
const path = parseRepositoryPath(input.path);
|
|
1723
|
+
const diagnostics = createCoreDiagnosticCollector(options.limits, operation);
|
|
1724
|
+
if (!isCanonicalManifestPath(path)) diagnostics.add({
|
|
1725
|
+
code: "MOLDEA_MANIFEST_PATH_INVALID",
|
|
1726
|
+
path
|
|
1727
|
+
});
|
|
1728
|
+
for (const diagnostic of normalized.diagnostics) diagnostics.merge(diagnostic);
|
|
1729
|
+
if (!normalized.valid || normalized.text === null) return freezeRecursively({
|
|
1730
|
+
asset: null,
|
|
1731
|
+
diagnostics: diagnostics.finalize(),
|
|
1732
|
+
formatVersion: null,
|
|
1733
|
+
manifest: null,
|
|
1734
|
+
valid: false
|
|
1735
|
+
});
|
|
1736
|
+
const locator = createSourceLocator(normalized.text.value);
|
|
1737
|
+
const parsed = parseStrictYaml(normalized.text.value, path, locator, diagnostics);
|
|
1738
|
+
const formatVersion = parsed.value === null ? null : detectSupportedManifestVersion(parsed.value);
|
|
1739
|
+
const manifest = parsed.valid && parsed.value !== null ? validateManifest(parsed.value, path, diagnostics, options.limits, operation) : null;
|
|
1740
|
+
if (manifest === null || diagnostics.size > 0) return freezeRecursively({
|
|
1741
|
+
asset: null,
|
|
1742
|
+
diagnostics: diagnostics.finalize(),
|
|
1743
|
+
formatVersion,
|
|
1744
|
+
manifest: null,
|
|
1745
|
+
valid: false
|
|
1746
|
+
});
|
|
1747
|
+
const digest = await calculateNormalizedTextDigest(normalized.text);
|
|
1748
|
+
const asset = {
|
|
1749
|
+
content: normalized.text.value,
|
|
1750
|
+
digest,
|
|
1751
|
+
path,
|
|
1752
|
+
scalarLength: normalized.text.scalarLength,
|
|
1753
|
+
utf8ByteLength: normalized.text.utf8ByteLength
|
|
1754
|
+
};
|
|
1755
|
+
return freezeRecursively({
|
|
1756
|
+
asset,
|
|
1757
|
+
diagnostics: diagnostics.finalize(),
|
|
1758
|
+
formatVersion,
|
|
1759
|
+
manifest,
|
|
1760
|
+
valid: true
|
|
1761
|
+
});
|
|
1762
|
+
};
|
|
1763
|
+
/**
|
|
1764
|
+
* Parses and validates one complete version 1 manifest document.
|
|
1765
|
+
* @param input The canonical logical path and exact manifest text or bytes.
|
|
1766
|
+
* @param options The immutable Core limit snapshot.
|
|
1767
|
+
* @returns A frozen all-or-nothing manifest parse result.
|
|
1768
|
+
* @throws
|
|
1769
|
+
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
1770
|
+
* - INVALID_ARGUMENT: The Core operation received an invalid argument.
|
|
1771
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1772
|
+
*/
|
|
1773
|
+
var parseManifestDocument = async (input, options, operation = "parse-manifest") => {
|
|
1774
|
+
const inspection = await inspectManifestDocument(input, options, operation);
|
|
1775
|
+
return freezeRecursively({
|
|
1776
|
+
asset: inspection.asset,
|
|
1777
|
+
diagnostics: inspection.diagnostics,
|
|
1778
|
+
manifest: inspection.manifest,
|
|
1779
|
+
valid: inspection.valid
|
|
1780
|
+
});
|
|
1781
|
+
};
|
|
1782
|
+
//#endregion
|
|
1783
|
+
//#region src/scope-matching/scope.ts
|
|
1784
|
+
/**
|
|
1785
|
+
* Parses a manifest and matches its repository relationships against changed logical paths.
|
|
1786
|
+
* @param input The canonical manifest document and untrusted changed-path collection.
|
|
1787
|
+
* @param options The immutable Core operation options.
|
|
1788
|
+
* @returns A promise resolving to frozen content-free scope metadata and matches.
|
|
1789
|
+
* @throws
|
|
1790
|
+
* - INVALID_REPOSITORY_PATH: The manifest path or a changed repository path is invalid.
|
|
1791
|
+
* - INVALID_ARGUMENT: The scope operation received an invalid argument.
|
|
1792
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1793
|
+
*/
|
|
1794
|
+
var matchManifestScope = async (input, options) => {
|
|
1795
|
+
const normalized = normalizeManifestScopeInput(input, options.limits);
|
|
1796
|
+
const inputDigest = await calculateManifestScopeInputDigest(normalized.paths);
|
|
1797
|
+
const parsed = await parseManifestDocument(normalized.manifest, options, "match-manifest-scope");
|
|
1798
|
+
if (!parsed.valid || parsed.asset === null || parsed.manifest === null) return freezeRecursively({
|
|
1799
|
+
counts: {
|
|
1800
|
+
declarations: 0,
|
|
1801
|
+
inputPaths: normalized.paths.length,
|
|
1802
|
+
matchedOwners: 0,
|
|
1803
|
+
matchedPaths: 0,
|
|
1804
|
+
matches: 0
|
|
1805
|
+
},
|
|
1806
|
+
diagnostics: parsed.diagnostics,
|
|
1807
|
+
inputDigest,
|
|
1808
|
+
manifestDigest: null,
|
|
1809
|
+
matches: [],
|
|
1810
|
+
relevant: false,
|
|
1811
|
+
valid: false
|
|
1812
|
+
});
|
|
1813
|
+
const matched = matchParsedManifestScope(parsed.manifest, normalized.paths, options.limits);
|
|
1814
|
+
return freezeRecursively({
|
|
1815
|
+
counts: matched.counts,
|
|
1816
|
+
diagnostics: [],
|
|
1817
|
+
inputDigest,
|
|
1818
|
+
manifestDigest: parsed.asset.digest,
|
|
1819
|
+
matches: matched.matches,
|
|
1820
|
+
relevant: matched.matches.length > 0,
|
|
1821
|
+
valid: true
|
|
1822
|
+
});
|
|
1823
|
+
};
|
|
1824
|
+
//#endregion
|
|
1825
|
+
export { createSourceLocator as a, calculateContentDigest as c, parseStrictYaml as i, calculateNormalizedTextDigest as l, inspectManifestDocument as n, collectManifestScopeDeclarations as o, parseManifestDocument as r, matchesRepositoryGlob as s, matchManifestScope as t, normalizeTextDocument as u };
|
|
1826
|
+
|
|
1827
|
+
//# sourceMappingURL=scope-AGMcHUE_.js.map
|