@moldea.ai/core 2.1.0 → 3.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 +37 -99
- package/dist/adapter/index.d.ts +97 -14
- package/dist/adapter/index.d.ts.map +1 -1
- package/dist/adapter-execution/index.d.ts.map +1 -1
- package/dist/adapter-repository/index.d.ts +9 -0
- package/dist/adapter-repository/index.d.ts.map +1 -0
- package/dist/adapter-validation/index.d.ts +2 -3
- package/dist/adapter-validation/index.d.ts.map +1 -1
- package/dist/adapter.js +93 -0
- package/dist/adapter.js.map +1 -0
- package/dist/agent-assets/index.d.ts +2 -2
- package/dist/agent-assets/index.d.ts.map +1 -1
- package/dist/canonical-content-page/index.d.ts +5 -0
- package/dist/canonical-content-page/index.d.ts.map +1 -0
- package/dist/canonical-discovery/index.d.ts +3 -2
- package/dist/canonical-discovery/index.d.ts.map +1 -1
- package/dist/chunks/exceptions-DWsZTpqs.js +71 -0
- package/dist/chunks/exceptions-DWsZTpqs.js.map +1 -0
- package/dist/contracts/index.d.ts +129 -6
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/decision/index.d.ts +1 -1
- package/dist/decision/index.d.ts.map +1 -1
- package/dist/decision-graph/index.d.ts +3 -2
- package/dist/decision-graph/index.d.ts.map +1 -1
- package/dist/exceptions/index.d.ts +2 -2
- package/dist/exceptions/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +688 -228
- package/dist/index.js.map +1 -1
- package/dist/manifest/index.d.ts +1 -1
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/mirrors/index.d.ts +3 -2
- package/dist/mirrors/index.d.ts.map +1 -1
- package/dist/project-assets/index.d.ts +4 -3
- package/dist/project-assets/index.d.ts.map +1 -1
- package/dist/project-inspection-page/index.d.ts +5 -0
- package/dist/project-inspection-page/index.d.ts.map +1 -0
- package/dist/project-metadata/index.d.ts +6 -0
- package/dist/project-metadata/index.d.ts.map +1 -0
- package/dist/{project-inspection → project-validation}/index.d.ts +8 -2
- package/dist/project-validation/index.d.ts.map +1 -0
- package/dist/repository-inspection-session/index.d.ts +13 -3
- package/dist/repository-inspection-session/index.d.ts.map +1 -1
- package/dist/repository-reference-validation/index.d.ts +3 -2
- package/dist/repository-reference-validation/index.d.ts.map +1 -1
- package/dist/repository-text/index.d.ts +3 -2
- package/dist/repository-text/index.d.ts.map +1 -1
- package/dist/runtime-guidance/index.d.ts +3 -2
- package/dist/runtime-guidance/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/project-inspection/index.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { n as CoreOperationException, t as CoreConfigurationException } from "./chunks/exceptions-DWsZTpqs.js";
|
|
2
|
+
import { REPOSITORY_ROOT, RepositoryPathException, RepositorySourceException, compareRepositoryPaths, createRepositoryIdentity, isRepositoryPath, parseRepositoryPath } from "@moldea.ai/repository";
|
|
3
3
|
import { Parser, isAlias, isMap, isScalar, isSeq, parseAllDocuments } from "yaml";
|
|
4
4
|
//#region src/constants/index.ts
|
|
5
5
|
var RECOGNIZED_RUNTIME_ADAPTER_IDS = Object.freeze([
|
|
@@ -25,69 +25,154 @@ var DEFAULT_CORE_RESOURCE_LIMITS = Object.freeze({
|
|
|
25
25
|
maxTotalBytesRead: 134217728
|
|
26
26
|
});
|
|
27
27
|
//#endregion
|
|
28
|
-
//#region src/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
var
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
28
|
+
//#region src/immutable/index.ts
|
|
29
|
+
/**
|
|
30
|
+
* Recursively freezes a Core-owned value without cloning it.
|
|
31
|
+
* @param value The detached acyclic value whose already-frozen objects are deeply frozen.
|
|
32
|
+
* @returns The same value with every mutable reachable object frozen.
|
|
33
|
+
*/
|
|
34
|
+
var freezeRecursively = (value) => {
|
|
35
|
+
if (typeof value !== "object" || value === null || Object.isFrozen(value)) return value;
|
|
36
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
37
|
+
const child = value[key];
|
|
38
|
+
freezeRecursively(child);
|
|
39
|
+
}
|
|
40
|
+
return Object.freeze(value);
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Creates a record that cannot collide with prototype-chain properties.
|
|
44
|
+
* @param entries The own string-keyed entries to assign.
|
|
45
|
+
* @returns A mutable null-prototype record for later normalization and freezing.
|
|
46
|
+
*/
|
|
47
|
+
var createNullPrototypeRecord = (entries) => {
|
|
48
|
+
const record = Object.create(null);
|
|
49
|
+
for (const [key, value] of entries) record[key] = value;
|
|
50
|
+
return record;
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/canonical-content-page/index.ts
|
|
54
|
+
var decoder$1 = new TextDecoder("utf-8", {
|
|
55
|
+
fatal: true,
|
|
56
|
+
ignoreBOM: true
|
|
57
|
+
});
|
|
58
|
+
var invalidArgument$4 = () => {
|
|
59
|
+
throw new CoreOperationException({
|
|
60
|
+
code: "INVALID_ARGUMENT",
|
|
61
|
+
operation: "read-canonical-content-page"
|
|
54
62
|
});
|
|
55
63
|
};
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
64
|
+
var invalidContent = () => {
|
|
65
|
+
throw new CoreOperationException({
|
|
66
|
+
code: "CONTENT_INVALID",
|
|
67
|
+
operation: "read-canonical-content-page"
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
var isRepositoryReader$1 = (candidate) => typeof candidate === "object" && candidate !== null && typeof candidate.getEntry === "function" && typeof candidate.readFilePage === "function";
|
|
71
|
+
var readBytes = async (repository, path, offset, maxBytes, signal) => {
|
|
72
|
+
const chunks = [];
|
|
73
|
+
let byteLength = 0;
|
|
74
|
+
let nextOffset = offset;
|
|
75
|
+
let lastPage = null;
|
|
76
|
+
let totalBytes = null;
|
|
77
|
+
while (byteLength < maxBytes) {
|
|
78
|
+
const page = await repository.readFilePage(path, {
|
|
79
|
+
maxBytes: maxBytes - byteLength,
|
|
80
|
+
offset: nextOffset,
|
|
81
|
+
...signal === void 0 ? {} : { signal }
|
|
82
|
+
});
|
|
83
|
+
if (page.snapshot.id !== repository.snapshot.id || page.offset !== nextOffset || page.bytes.byteLength > maxBytes - byteLength || page.totalBytes < page.offset + page.bytes.byteLength || totalBytes !== null && page.totalBytes !== totalBytes || page.bytes.byteLength === 0 && !page.isComplete) throw new RepositorySourceException({
|
|
84
|
+
code: "INVALID_SOURCE_DATA",
|
|
85
|
+
operation: "read-file-page",
|
|
86
|
+
path,
|
|
87
|
+
retryable: false
|
|
88
|
+
});
|
|
89
|
+
chunks.push(page.bytes);
|
|
90
|
+
byteLength += page.bytes.byteLength;
|
|
91
|
+
totalBytes = page.totalBytes;
|
|
92
|
+
lastPage = page;
|
|
93
|
+
if (page.isComplete || byteLength === maxBytes) break;
|
|
94
|
+
if (page.nextOffset !== page.offset + page.bytes.byteLength) throw new RepositorySourceException({
|
|
95
|
+
code: "INVALID_SOURCE_DATA",
|
|
96
|
+
operation: "read-file-page",
|
|
97
|
+
path,
|
|
98
|
+
retryable: false
|
|
99
|
+
});
|
|
100
|
+
nextOffset = page.nextOffset;
|
|
90
101
|
}
|
|
102
|
+
if (lastPage === null) return invalidArgument$4();
|
|
103
|
+
const bytes = new Uint8Array(byteLength);
|
|
104
|
+
let writeOffset = 0;
|
|
105
|
+
for (const chunk of chunks) {
|
|
106
|
+
bytes.set(chunk, writeOffset);
|
|
107
|
+
writeOffset += chunk.byteLength;
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
bytes,
|
|
111
|
+
lastPage
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
var decodeSafePrefix = (bytes, maximumBytes) => {
|
|
115
|
+
const minimumCandidate = Math.max(0, maximumBytes - 3);
|
|
116
|
+
for (let end = maximumBytes; end >= minimumCandidate; end -= 1) try {
|
|
117
|
+
const content = decoder$1.decode(bytes.subarray(0, end));
|
|
118
|
+
if (end === 0 && bytes.byteLength > 0) continue;
|
|
119
|
+
return [content, end];
|
|
120
|
+
} catch {}
|
|
121
|
+
return invalidContent();
|
|
122
|
+
};
|
|
123
|
+
/** Reads one explicit canonical file range without materializing the complete file. */
|
|
124
|
+
var readCanonicalContentPage = async (input, options) => {
|
|
125
|
+
if (typeof input !== "object" || input === null || Reflect.ownKeys(input).some((key) => key !== "maxBytes" && key !== "offset" && key !== "path" && key !== "repository" && key !== "signal") || !isRepositoryReader$1(input.repository) || !Number.isSafeInteger(input.maxBytes) || input.maxBytes < 1 || input.maxBytes > options.limits.maxFileBytes || !Number.isSafeInteger(input.offset) || input.offset < 0) return invalidArgument$4();
|
|
126
|
+
const path = parseRepositoryPath(input.path);
|
|
127
|
+
if (!path.startsWith("/moldea/")) return invalidArgument$4();
|
|
128
|
+
const operationOptions = input.signal === void 0 ? void 0 : { signal: input.signal };
|
|
129
|
+
const entry = await input.repository.getEntry(path, operationOptions);
|
|
130
|
+
if (entry === null) throw new RepositorySourceException({
|
|
131
|
+
code: "ENTRY_NOT_FOUND",
|
|
132
|
+
operation: "read-file-page",
|
|
133
|
+
path,
|
|
134
|
+
retryable: false
|
|
135
|
+
});
|
|
136
|
+
if (entry.type !== "file" || entry.byteLength === null) throw new RepositorySourceException({
|
|
137
|
+
code: "ENTRY_NOT_FILE",
|
|
138
|
+
operation: "read-file-page",
|
|
139
|
+
path,
|
|
140
|
+
retryable: false
|
|
141
|
+
});
|
|
142
|
+
if (entry.byteLength > options.limits.maxFileBytes) throw new CoreOperationException({
|
|
143
|
+
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
144
|
+
limit: "maxFileBytes",
|
|
145
|
+
operation: "read-canonical-content-page"
|
|
146
|
+
});
|
|
147
|
+
if (input.offset > entry.byteLength) return invalidArgument$4();
|
|
148
|
+
if (input.offset === entry.byteLength) return freezeRecursively({
|
|
149
|
+
byteEnd: input.offset,
|
|
150
|
+
byteStart: input.offset,
|
|
151
|
+
content: "",
|
|
152
|
+
contentIdentity: entry.contentIdentity,
|
|
153
|
+
isComplete: true,
|
|
154
|
+
nextOffset: null,
|
|
155
|
+
path,
|
|
156
|
+
source: input.repository.snapshot,
|
|
157
|
+
totalBytes: entry.byteLength
|
|
158
|
+
});
|
|
159
|
+
const lookaheadBytes = Math.min(entry.byteLength - input.offset, input.maxBytes + 3);
|
|
160
|
+
const { bytes, lastPage } = await readBytes(input.repository, path, input.offset, lookaheadBytes, input.signal);
|
|
161
|
+
if (lastPage.totalBytes !== entry.byteLength || (bytes[0] & 192) === 128) return invalidArgument$4();
|
|
162
|
+
const [content, consumedBytes] = decodeSafePrefix(bytes, Math.min(input.maxBytes, bytes.byteLength));
|
|
163
|
+
const byteEnd = input.offset + consumedBytes;
|
|
164
|
+
const isComplete = byteEnd === entry.byteLength;
|
|
165
|
+
return freezeRecursively({
|
|
166
|
+
byteEnd,
|
|
167
|
+
byteStart: input.offset,
|
|
168
|
+
content,
|
|
169
|
+
contentIdentity: entry.contentIdentity,
|
|
170
|
+
isComplete,
|
|
171
|
+
nextOffset: isComplete ? null : byteEnd,
|
|
172
|
+
path,
|
|
173
|
+
source: input.repository.snapshot,
|
|
174
|
+
totalBytes: entry.byteLength
|
|
175
|
+
});
|
|
91
176
|
};
|
|
92
177
|
//#endregion
|
|
93
178
|
//#region src/format-validation/index.ts
|
|
@@ -248,31 +333,6 @@ var sortRepositoryReferences = (references) => {
|
|
|
248
333
|
});
|
|
249
334
|
};
|
|
250
335
|
//#endregion
|
|
251
|
-
//#region src/immutable/index.ts
|
|
252
|
-
/**
|
|
253
|
-
* Recursively freezes a Core-owned value without cloning it.
|
|
254
|
-
* @param value The detached acyclic value whose already-frozen objects are deeply frozen.
|
|
255
|
-
* @returns The same value with every mutable reachable object frozen.
|
|
256
|
-
*/
|
|
257
|
-
var freezeRecursively = (value) => {
|
|
258
|
-
if (typeof value !== "object" || value === null || Object.isFrozen(value)) return value;
|
|
259
|
-
for (const key of Reflect.ownKeys(value)) {
|
|
260
|
-
const child = value[key];
|
|
261
|
-
freezeRecursively(child);
|
|
262
|
-
}
|
|
263
|
-
return Object.freeze(value);
|
|
264
|
-
};
|
|
265
|
-
/**
|
|
266
|
-
* Creates a record that cannot collide with prototype-chain properties.
|
|
267
|
-
* @param entries The own string-keyed entries to assign.
|
|
268
|
-
* @returns A mutable null-prototype record for later normalization and freezing.
|
|
269
|
-
*/
|
|
270
|
-
var createNullPrototypeRecord = (entries) => {
|
|
271
|
-
const record = Object.create(null);
|
|
272
|
-
for (const [key, value] of entries) record[key] = value;
|
|
273
|
-
return record;
|
|
274
|
-
};
|
|
275
|
-
//#endregion
|
|
276
336
|
//#region src/diagnostic-utilities/index.ts
|
|
277
337
|
var CORE_DIAGNOSTIC_MESSAGES = {
|
|
278
338
|
MOLDEA_AGENT_DESCRIPTION_INVALID: "The agent description is invalid.",
|
|
@@ -904,7 +964,7 @@ var createSourceLocator = (value) => {
|
|
|
904
964
|
};
|
|
905
965
|
//#endregion
|
|
906
966
|
//#region src/text/index.ts
|
|
907
|
-
var encoder = new TextEncoder();
|
|
967
|
+
var encoder$1 = new TextEncoder();
|
|
908
968
|
var decoder = new TextDecoder("utf-8", {
|
|
909
969
|
fatal: true,
|
|
910
970
|
ignoreBOM: true
|
|
@@ -982,7 +1042,7 @@ var collectNulDiagnostics = (value, path, diagnostics) => {
|
|
|
982
1042
|
offset += 1;
|
|
983
1043
|
}
|
|
984
1044
|
};
|
|
985
|
-
var invalidArgument$
|
|
1045
|
+
var invalidArgument$3 = (operation) => {
|
|
986
1046
|
throw new CoreOperationException({
|
|
987
1047
|
code: "INVALID_ARGUMENT",
|
|
988
1048
|
operation
|
|
@@ -1017,10 +1077,10 @@ var invalidResult = (diagnostics) => {
|
|
|
1017
1077
|
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1018
1078
|
*/
|
|
1019
1079
|
var readInput = (input, limits, operation, limit, diagnostics) => {
|
|
1020
|
-
if (!isRecord$3(input)) return invalidArgument$
|
|
1080
|
+
if (!isRecord$3(input)) return invalidArgument$3(operation);
|
|
1021
1081
|
const pathCandidate = input["path"];
|
|
1022
1082
|
const content = input["content"];
|
|
1023
|
-
if (typeof pathCandidate !== "string" || typeof content !== "string" && !(content instanceof Uint8Array)) return invalidArgument$
|
|
1083
|
+
if (typeof pathCandidate !== "string" || typeof content !== "string" && !(content instanceof Uint8Array)) return invalidArgument$3(operation);
|
|
1024
1084
|
const path = parseRepositoryPath(pathCandidate);
|
|
1025
1085
|
if (typeof content === "string") {
|
|
1026
1086
|
const byteLength = measureScalarUtf8ByteLength(content, limits[limit]);
|
|
@@ -1075,7 +1135,7 @@ var normalizeTextDocument = (input, limits, operation, limit = "maxFileBytes") =
|
|
|
1075
1135
|
diagnostics: [],
|
|
1076
1136
|
text: freezeRecursively({
|
|
1077
1137
|
scalarLength: countUnicodeScalars(value),
|
|
1078
|
-
utf8ByteLength: encoder.encode(value).byteLength,
|
|
1138
|
+
utf8ByteLength: encoder$1.encode(value).byteLength,
|
|
1079
1139
|
value
|
|
1080
1140
|
}),
|
|
1081
1141
|
valid: true
|
|
@@ -1092,7 +1152,7 @@ var toLowercaseHex = (bytes) => {
|
|
|
1092
1152
|
* @returns A promise resolving to the canonical lowercase SHA-256 digest.
|
|
1093
1153
|
*/
|
|
1094
1154
|
var calculateNormalizedTextDigest = async (text) => {
|
|
1095
|
-
const bytes = encoder.encode(text.value);
|
|
1155
|
+
const bytes = encoder$1.encode(text.value);
|
|
1096
1156
|
return `sha256:${toLowercaseHex(new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", bytes)))}`;
|
|
1097
1157
|
};
|
|
1098
1158
|
/**
|
|
@@ -2240,6 +2300,57 @@ var parseManifestDocument = async (input, options, operation = "parse-manifest")
|
|
|
2240
2300
|
});
|
|
2241
2301
|
};
|
|
2242
2302
|
//#endregion
|
|
2303
|
+
//#region src/project-metadata/index.ts
|
|
2304
|
+
var createAssetItem = (asset, kind, agentId = null, decisionId = null) => ({
|
|
2305
|
+
agentId,
|
|
2306
|
+
byteLength: asset.utf8ByteLength,
|
|
2307
|
+
canonicalDigest: null,
|
|
2308
|
+
decisionId,
|
|
2309
|
+
digest: asset.digest,
|
|
2310
|
+
kind,
|
|
2311
|
+
path: asset.path,
|
|
2312
|
+
scalarLength: asset.scalarLength
|
|
2313
|
+
});
|
|
2314
|
+
var compareMetadataItems = (left, right) => compareExactStrings(left.path, right.path) || compareExactStrings(left.kind, right.kind) || compareExactStrings(left.agentId ?? "", right.agentId ?? "");
|
|
2315
|
+
/** Collects deterministic content-free asset metadata from one validated project. */
|
|
2316
|
+
var collectProjectMetadata = (project) => {
|
|
2317
|
+
const items = [createAssetItem(project.manifest.asset, "manifest"), createAssetItem(project.project, "project")];
|
|
2318
|
+
for (const context of project.context) items.push(createAssetItem(context.asset, "context"));
|
|
2319
|
+
for (const { decision } of project.decisions) items.push(createAssetItem(decision.asset, "decision", null, decision.id));
|
|
2320
|
+
for (const runtime of project.runtimes) items.push(createAssetItem(runtime.asset, "runtime-guidance"));
|
|
2321
|
+
for (const agent of project.agents) {
|
|
2322
|
+
items.push(createAssetItem(agent.description.asset, "agent-description", agent.id));
|
|
2323
|
+
items.push(createAssetItem(agent.instruction, "agent-instruction", agent.id));
|
|
2324
|
+
if (agent.handoffDescription !== null) items.push(createAssetItem(agent.handoffDescription.asset, "agent-handoff-description", agent.id));
|
|
2325
|
+
for (const mirror of agent.mirrors) items.push({
|
|
2326
|
+
agentId: agent.id,
|
|
2327
|
+
byteLength: mirror.byteLength,
|
|
2328
|
+
canonicalDigest: mirror.canonicalDigest,
|
|
2329
|
+
decisionId: null,
|
|
2330
|
+
digest: mirror.digest,
|
|
2331
|
+
kind: "mirror",
|
|
2332
|
+
path: mirror.path,
|
|
2333
|
+
scalarLength: mirror.scalarLength
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2336
|
+
return items.sort(compareMetadataItems);
|
|
2337
|
+
};
|
|
2338
|
+
/** Creates the content-free summary for one validated project snapshot. */
|
|
2339
|
+
var createProjectSummary = (project) => ({
|
|
2340
|
+
counts: {
|
|
2341
|
+
agents: project.agents.length,
|
|
2342
|
+
context: project.context.length,
|
|
2343
|
+
decisions: project.decisions.length,
|
|
2344
|
+
mirrors: project.agents.reduce((count, agent) => count + agent.mirrors.length, 0),
|
|
2345
|
+
runtimes: project.runtimes.length,
|
|
2346
|
+
unresolved: Object.keys(project.unresolved).length
|
|
2347
|
+
},
|
|
2348
|
+
manifestDigest: project.manifest.asset.digest,
|
|
2349
|
+
manifestPath: project.manifest.asset.path,
|
|
2350
|
+
projectDigest: project.project.digest,
|
|
2351
|
+
projectPath: project.project.path
|
|
2352
|
+
});
|
|
2353
|
+
//#endregion
|
|
2243
2354
|
//#region src/adapter-availability/index.ts
|
|
2244
2355
|
/**
|
|
2245
2356
|
* Validates adapter availability and format support before any runtime adapter runs.
|
|
@@ -2251,7 +2362,7 @@ var parseManifestDocument = async (input, options, operation = "parse-manifest")
|
|
|
2251
2362
|
* - RESOURCE_LIMIT_EXCEEDED: The raw Core diagnostic limit was exceeded.
|
|
2252
2363
|
*/
|
|
2253
2364
|
var validateRuntimeAdapterAvailability = (locations, formatVersion, options) => {
|
|
2254
|
-
const diagnostics = createCoreDiagnosticCollector(options.limits, "
|
|
2365
|
+
const diagnostics = createCoreDiagnosticCollector(options.limits, "validate-project");
|
|
2255
2366
|
const adapters = new Map(options.adapters.map((adapter) => [adapter.id, adapter]));
|
|
2256
2367
|
for (const location of locations) {
|
|
2257
2368
|
if (location.adapterId === "custom") continue;
|
|
@@ -2589,18 +2700,58 @@ var validateRuntimeAdapterResult = async (candidate, context, outputCounts) => {
|
|
|
2589
2700
|
//#endregion
|
|
2590
2701
|
//#region src/adapter-execution/index.ts
|
|
2591
2702
|
var isInspectionBoundaryFailure = (error) => {
|
|
2592
|
-
return error instanceof RepositoryPathException || error instanceof RepositorySourceException || error instanceof CoreOperationException && error.operation === "
|
|
2593
|
-
};
|
|
2594
|
-
var
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2703
|
+
return error instanceof RepositoryPathException || error instanceof RepositorySourceException || error instanceof CoreOperationException && error.operation === "validate-project" && (error.code === "ABORTED" || error.code === "RESOURCE_LIMIT_EXCEEDED");
|
|
2704
|
+
};
|
|
2705
|
+
var getRuntimeBindingKey = (reference) => JSON.stringify([reference.path, reference.symbol ?? null]);
|
|
2706
|
+
/** Builds one compact exact-binding index for a single configured runtime. */
|
|
2707
|
+
var createRuntimeAgentBindingIndex = (agents) => {
|
|
2708
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
2709
|
+
for (const agent of agents) {
|
|
2710
|
+
const runtimeAgent = agent.declaration.bindings?.runtimeAgent;
|
|
2711
|
+
if (runtimeAgent === void 0) continue;
|
|
2712
|
+
const key = getRuntimeBindingKey(runtimeAgent);
|
|
2713
|
+
const existing = candidates.get(key);
|
|
2714
|
+
if (existing !== void 0) {
|
|
2715
|
+
candidates.set(key, {
|
|
2716
|
+
candidateCount: existing.kind === "matched" ? 2 : existing.candidateCount + 1,
|
|
2717
|
+
kind: "ambiguous"
|
|
2718
|
+
});
|
|
2719
|
+
continue;
|
|
2720
|
+
}
|
|
2721
|
+
candidates.set(key, {
|
|
2722
|
+
agent,
|
|
2723
|
+
kind: "matched",
|
|
2724
|
+
resolved: freezeRecursively({
|
|
2725
|
+
declaration: agent.declaration,
|
|
2726
|
+
description: agent.description,
|
|
2727
|
+
handoffDescription: agent.handoffDescription,
|
|
2728
|
+
id: agent.id
|
|
2729
|
+
})
|
|
2730
|
+
});
|
|
2731
|
+
}
|
|
2732
|
+
return candidates;
|
|
2733
|
+
};
|
|
2734
|
+
var invokeAdapter = async (adapter, agent, agentBindings, project, session, options, outputCounts, signal) => {
|
|
2735
|
+
const scopedAgent = freezeRecursively(agent);
|
|
2736
|
+
const resolvedAgents = /* @__PURE__ */ new Map([[scopedAgent.id, scopedAgent]]);
|
|
2737
|
+
const repository = session.adapterRepository;
|
|
2738
|
+
const resolveAgent = (reference) => {
|
|
2739
|
+
const resolution = agentBindings.get(getRuntimeBindingKey(reference));
|
|
2740
|
+
if (resolution === void 0) return Object.freeze({ kind: "absent" });
|
|
2741
|
+
if (resolution.kind === "ambiguous") return Object.freeze({
|
|
2742
|
+
candidateCount: resolution.candidateCount,
|
|
2743
|
+
kind: "ambiguous"
|
|
2744
|
+
});
|
|
2745
|
+
resolvedAgents.set(resolution.agent.id, resolution.agent);
|
|
2746
|
+
return Object.freeze({
|
|
2747
|
+
agent: resolution.resolved,
|
|
2748
|
+
kind: "matched"
|
|
2749
|
+
});
|
|
2750
|
+
};
|
|
2600
2751
|
const context = Object.freeze({
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2752
|
+
agent: scopedAgent,
|
|
2753
|
+
repository,
|
|
2754
|
+
resolveAgent,
|
|
2604
2755
|
...signal === void 0 ? {} : { signal }
|
|
2605
2756
|
});
|
|
2606
2757
|
let candidate;
|
|
@@ -2615,15 +2766,15 @@ var invokeAdapter = async (adapter, project, session, options, outputCounts, sig
|
|
|
2615
2766
|
adapterId: adapter.id,
|
|
2616
2767
|
cause: error,
|
|
2617
2768
|
code: "ADAPTER_EXECUTION_FAILED",
|
|
2618
|
-
operation: "
|
|
2769
|
+
operation: "validate-project"
|
|
2619
2770
|
});
|
|
2620
2771
|
}
|
|
2621
2772
|
return validateRuntimeAdapterResult(candidate, {
|
|
2622
2773
|
adapterId: adapter.id,
|
|
2623
|
-
agents,
|
|
2774
|
+
agents: [...resolvedAgents.values()],
|
|
2624
2775
|
limits: options.limits,
|
|
2625
2776
|
project,
|
|
2626
|
-
repository: session.
|
|
2777
|
+
repository: session.adapterRepository,
|
|
2627
2778
|
...signal === void 0 ? {} : { signal }
|
|
2628
2779
|
}, outputCounts);
|
|
2629
2780
|
};
|
|
@@ -2654,10 +2805,20 @@ var inspectRuntimeAdapters = async (project, session, options, signal) => {
|
|
|
2654
2805
|
diagnostics: 0,
|
|
2655
2806
|
evidence: 0
|
|
2656
2807
|
};
|
|
2808
|
+
const agentsByRuntimeId = /* @__PURE__ */ new Map();
|
|
2809
|
+
for (const agent of project.agents) {
|
|
2810
|
+
const runtimeAgents = agentsByRuntimeId.get(agent.declaration.runtime.id);
|
|
2811
|
+
if (runtimeAgents === void 0) agentsByRuntimeId.set(agent.declaration.runtime.id, [agent]);
|
|
2812
|
+
else runtimeAgents.push(agent);
|
|
2813
|
+
}
|
|
2657
2814
|
for (const adapter of options.adapters) {
|
|
2658
|
-
const
|
|
2659
|
-
|
|
2660
|
-
|
|
2815
|
+
const agents = agentsByRuntimeId.get(adapter.id) ?? [];
|
|
2816
|
+
const agentBindings = createRuntimeAgentBindingIndex(agents);
|
|
2817
|
+
for (const agent of agents) {
|
|
2818
|
+
const result = await invokeAdapter(adapter, agent, agentBindings, project, session, options, outputCounts, signal);
|
|
2819
|
+
evidence.push(...result.evidence);
|
|
2820
|
+
diagnostics.push(...result.diagnostics);
|
|
2821
|
+
}
|
|
2661
2822
|
}
|
|
2662
2823
|
return freezeRecursively({
|
|
2663
2824
|
diagnostics: normalizeDiagnostics(diagnostics),
|
|
@@ -2667,6 +2828,8 @@ var inspectRuntimeAdapters = async (project, session, options, signal) => {
|
|
|
2667
2828
|
//#endregion
|
|
2668
2829
|
//#region src/repository-inspection-session/index.ts
|
|
2669
2830
|
var MANIFEST_PATH$3 = parseRepositoryPath("/moldea/moldea.yaml");
|
|
2831
|
+
var SOURCE_PAGE_ENTRIES = 256;
|
|
2832
|
+
var SOURCE_PAGE_BYTES = 65536;
|
|
2670
2833
|
var invalidSourceData$3 = (operation, path) => {
|
|
2671
2834
|
throw new RepositorySourceException({
|
|
2672
2835
|
code: "INVALID_SOURCE_DATA",
|
|
@@ -2680,11 +2843,16 @@ var copyReaderEntry$1 = (candidate, operation, fallbackPath, expectedPath) => {
|
|
|
2680
2843
|
const record = candidate;
|
|
2681
2844
|
const pathCandidate = record["path"];
|
|
2682
2845
|
const typeCandidate = record["type"];
|
|
2846
|
+
const byteLength = record["byteLength"];
|
|
2847
|
+
const contentIdentity = record["contentIdentity"];
|
|
2683
2848
|
if (typeof pathCandidate !== "string" || !isRepositoryPath(pathCandidate)) return invalidSourceData$3(operation, fallbackPath);
|
|
2684
2849
|
const path = parseRepositoryPath(pathCandidate);
|
|
2685
2850
|
if (expectedPath !== void 0 && path !== expectedPath) return invalidSourceData$3(operation, path);
|
|
2686
2851
|
if (typeCandidate !== "file" && typeCandidate !== "directory" && typeCandidate !== "symlink") return invalidSourceData$3(operation, path);
|
|
2852
|
+
if (typeCandidate === "file" ? !Number.isSafeInteger(byteLength) || byteLength < 0 || contentIdentity !== null && typeof contentIdentity !== "string" : byteLength !== null || contentIdentity !== null) return invalidSourceData$3(operation, path);
|
|
2687
2853
|
return {
|
|
2854
|
+
byteLength,
|
|
2855
|
+
contentIdentity,
|
|
2688
2856
|
path,
|
|
2689
2857
|
type: typeCandidate
|
|
2690
2858
|
};
|
|
@@ -2698,11 +2866,11 @@ var throwResourceLimitExceeded = (limit) => {
|
|
|
2698
2866
|
throw new CoreOperationException({
|
|
2699
2867
|
code: "RESOURCE_LIMIT_EXCEEDED",
|
|
2700
2868
|
limit,
|
|
2701
|
-
operation: "
|
|
2869
|
+
operation: "validate-project"
|
|
2702
2870
|
});
|
|
2703
2871
|
};
|
|
2704
2872
|
var createSourceOptions = (sessionSignal, operationSignal) => {
|
|
2705
|
-
const signal = sessionSignal
|
|
2873
|
+
const signal = sessionSignal === void 0 ? operationSignal : operationSignal === void 0 || operationSignal === sessionSignal ? sessionSignal : AbortSignal.any([sessionSignal, operationSignal]);
|
|
2706
2874
|
return signal === void 0 ? void 0 : { signal };
|
|
2707
2875
|
};
|
|
2708
2876
|
/**
|
|
@@ -2710,19 +2878,25 @@ var createSourceOptions = (sessionSignal, operationSignal) => {
|
|
|
2710
2878
|
* @param repository The source-neutral reader bound to one coherent snapshot.
|
|
2711
2879
|
* @param limits The immutable resource limits for the inspection.
|
|
2712
2880
|
* @param signal Optional cancellation shared by every inspection operation.
|
|
2713
|
-
* @returns A
|
|
2881
|
+
* @returns A session that pages source metadata and range-reads bounded canonical files.
|
|
2714
2882
|
* @throws
|
|
2715
2883
|
* - ABORTED: Repository inspection was aborted before the session was created.
|
|
2716
2884
|
*/
|
|
2717
2885
|
var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
2718
|
-
const readCache = /* @__PURE__ */ new Map();
|
|
2719
2886
|
const seenPaths = /* @__PURE__ */ new Set();
|
|
2720
2887
|
let totalBytesRead = 0;
|
|
2888
|
+
const adapterLimits = Object.freeze({
|
|
2889
|
+
maxEntries: limits.maxEntries,
|
|
2890
|
+
maxFileBytes: limits.maxFileBytes,
|
|
2891
|
+
maxPageBytes: Math.min(SOURCE_PAGE_BYTES, limits.maxFileBytes),
|
|
2892
|
+
maxPageEntries: Math.min(SOURCE_PAGE_ENTRIES, limits.maxEntries),
|
|
2893
|
+
maxTotalBytesRead: limits.maxTotalBytesRead
|
|
2894
|
+
});
|
|
2721
2895
|
const createAbortedException = (abortedSignal) => {
|
|
2722
2896
|
return new CoreOperationException({
|
|
2723
2897
|
cause: abortedSignal.reason,
|
|
2724
2898
|
code: "ABORTED",
|
|
2725
|
-
operation: "
|
|
2899
|
+
operation: "validate-project"
|
|
2726
2900
|
});
|
|
2727
2901
|
};
|
|
2728
2902
|
const registerPath = (path) => {
|
|
@@ -2732,10 +2906,13 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
2732
2906
|
};
|
|
2733
2907
|
const throwIfSignalAborted = (operationSignal) => {
|
|
2734
2908
|
const abortedSignal = signal?.aborted ? signal : operationSignal?.aborted ? operationSignal : null;
|
|
2735
|
-
if (abortedSignal
|
|
2736
|
-
throw createAbortedException(abortedSignal);
|
|
2909
|
+
if (abortedSignal !== null) throw createAbortedException(abortedSignal);
|
|
2737
2910
|
};
|
|
2738
2911
|
throwIfSignalAborted();
|
|
2912
|
+
const reserveReadBytes = (byteLength) => {
|
|
2913
|
+
if (byteLength > limits.maxTotalBytesRead - totalBytesRead) return throwResourceLimitExceeded("maxTotalBytesRead");
|
|
2914
|
+
totalBytesRead += byteLength;
|
|
2915
|
+
};
|
|
2739
2916
|
const getEntry = async (path, options) => {
|
|
2740
2917
|
const parsedPath = parseRepositoryPath(path);
|
|
2741
2918
|
throwIfSignalAborted(options?.signal);
|
|
@@ -2744,82 +2921,184 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
2744
2921
|
throwIfSignalAborted(options?.signal);
|
|
2745
2922
|
return candidate === null ? null : copyReaderEntry$1(candidate, "get-entry", parsedPath, parsedPath);
|
|
2746
2923
|
};
|
|
2747
|
-
const
|
|
2924
|
+
const iterateEntries = (options) => {
|
|
2748
2925
|
const prefix = options?.prefix === void 0 ? REPOSITORY_ROOT : parseRepositoryPath(options.prefix);
|
|
2749
2926
|
return { async *[Symbol.asyncIterator]() {
|
|
2750
|
-
throwIfSignalAborted(options?.signal);
|
|
2751
2927
|
registerPath(prefix);
|
|
2752
2928
|
const yieldedPaths = /* @__PURE__ */ new Set();
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
...sourceOptions
|
|
2757
|
-
};
|
|
2758
|
-
for await (const candidate of repository.listEntries(sourceListOptions)) {
|
|
2929
|
+
let cursor;
|
|
2930
|
+
let previousPath = null;
|
|
2931
|
+
do {
|
|
2759
2932
|
throwIfSignalAborted(options?.signal);
|
|
2760
|
-
const
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2933
|
+
const page = await repository.listEntriesPage({
|
|
2934
|
+
...cursor === void 0 ? {} : { cursor },
|
|
2935
|
+
maxEntries: Math.min(SOURCE_PAGE_ENTRIES, limits.maxEntries),
|
|
2936
|
+
prefix,
|
|
2937
|
+
...createSourceOptions(signal, options?.signal) ?? {}
|
|
2938
|
+
});
|
|
2939
|
+
if (page.snapshot.id !== repository.snapshot.id || page.entries.length === 0 && !page.isComplete) return invalidSourceData$3("list-entries-page", prefix);
|
|
2940
|
+
for (const candidate of page.entries) {
|
|
2941
|
+
throwIfSignalAborted(options?.signal);
|
|
2942
|
+
const entry = copyReaderEntry$1(candidate, "list-entries-page", prefix);
|
|
2943
|
+
if (!isStrictDescendant(entry.path, prefix) || yieldedPaths.has(entry.path) || previousPath !== null && compareRepositoryPaths(previousPath, entry.path) >= 0) return invalidSourceData$3("list-entries-page", entry.path);
|
|
2944
|
+
yieldedPaths.add(entry.path);
|
|
2945
|
+
previousPath = entry.path;
|
|
2946
|
+
registerPath(entry.path);
|
|
2947
|
+
yield entry;
|
|
2948
|
+
}
|
|
2949
|
+
if (page.isComplete) {
|
|
2950
|
+
if (page.nextCursor !== null) return invalidSourceData$3("list-entries-page", prefix);
|
|
2951
|
+
return;
|
|
2952
|
+
}
|
|
2953
|
+
if (page.nextCursor === null || page.nextCursor === cursor) return invalidSourceData$3("list-entries-page", prefix);
|
|
2954
|
+
cursor = page.nextCursor;
|
|
2955
|
+
} while (true);
|
|
2767
2956
|
} };
|
|
2768
2957
|
};
|
|
2769
|
-
const loadFile = async (path) => {
|
|
2770
|
-
const content = await repository.readFile(path, createSourceOptions(signal, void 0));
|
|
2771
|
-
throwIfSignalAborted();
|
|
2772
|
-
if (!(content instanceof Uint8Array)) return invalidSourceData$3("read-file", path);
|
|
2958
|
+
const loadFile = async (path, operationSignal) => {
|
|
2773
2959
|
const fileLimit = path === MANIFEST_PATH$3 ? "maxManifestBytes" : "maxFileBytes";
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2960
|
+
const firstPage = await repository.readFilePage(path, {
|
|
2961
|
+
maxBytes: Math.min(SOURCE_PAGE_BYTES, Math.max(1, limits[fileLimit])),
|
|
2962
|
+
offset: 0,
|
|
2963
|
+
...createSourceOptions(signal, operationSignal) ?? {}
|
|
2964
|
+
});
|
|
2965
|
+
throwIfSignalAborted(operationSignal);
|
|
2966
|
+
if (firstPage.snapshot.id !== repository.snapshot.id || firstPage.offset !== 0 || !(firstPage.bytes instanceof Uint8Array) || !Number.isSafeInteger(firstPage.totalBytes) || firstPage.totalBytes < 0 || firstPage.bytes.byteLength > SOURCE_PAGE_BYTES || firstPage.bytes.byteLength > firstPage.totalBytes || firstPage.bytes.byteLength === 0 && !firstPage.isComplete) return invalidSourceData$3("read-file-page", path);
|
|
2967
|
+
if (firstPage.totalBytes > limits[fileLimit]) return throwResourceLimitExceeded(fileLimit);
|
|
2968
|
+
reserveReadBytes(firstPage.totalBytes);
|
|
2969
|
+
const content = new Uint8Array(firstPage.totalBytes);
|
|
2970
|
+
let offset = 0;
|
|
2971
|
+
let page = firstPage;
|
|
2972
|
+
let isFirstPage = true;
|
|
2973
|
+
while (isFirstPage || offset < content.byteLength) {
|
|
2974
|
+
isFirstPage = false;
|
|
2975
|
+
if (page.snapshot.id !== repository.snapshot.id || page.offset !== offset || page.totalBytes !== content.byteLength || !(page.bytes instanceof Uint8Array) || page.bytes.byteLength > SOURCE_PAGE_BYTES || page.bytes.byteLength > content.byteLength - offset || page.bytes.byteLength === 0 && !page.isComplete) return invalidSourceData$3("read-file-page", path);
|
|
2976
|
+
content.set(page.bytes, offset);
|
|
2977
|
+
offset += page.bytes.byteLength;
|
|
2978
|
+
if (page.isComplete) {
|
|
2979
|
+
if (page.nextOffset !== null || offset !== content.byteLength) return invalidSourceData$3("read-file-page", path);
|
|
2980
|
+
break;
|
|
2981
|
+
}
|
|
2982
|
+
if (page.nextOffset !== offset) return invalidSourceData$3("read-file-page", path);
|
|
2983
|
+
page = await repository.readFilePage(path, {
|
|
2984
|
+
maxBytes: Math.min(SOURCE_PAGE_BYTES, Math.max(1, content.byteLength - offset)),
|
|
2985
|
+
offset,
|
|
2986
|
+
...createSourceOptions(signal, operationSignal) ?? {}
|
|
2987
|
+
});
|
|
2988
|
+
throwIfSignalAborted(operationSignal);
|
|
2785
2989
|
}
|
|
2990
|
+
return content;
|
|
2786
2991
|
};
|
|
2787
|
-
const
|
|
2788
|
-
|
|
2789
|
-
if (
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2992
|
+
const awaitWithCancellation = async (promise, operationSignal) => {
|
|
2993
|
+
const callerSignal = createSourceOptions(signal, operationSignal)?.signal;
|
|
2994
|
+
if (callerSignal === void 0) return promise;
|
|
2995
|
+
if (callerSignal.aborted) throw createAbortedException(callerSignal);
|
|
2996
|
+
return new Promise((resolve, reject) => {
|
|
2997
|
+
const cleanup = () => callerSignal.removeEventListener("abort", abort);
|
|
2998
|
+
const abort = () => {
|
|
2999
|
+
cleanup();
|
|
3000
|
+
reject(createAbortedException(callerSignal));
|
|
2795
3001
|
};
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
3002
|
+
callerSignal.addEventListener("abort", abort, { once: true });
|
|
3003
|
+
promise.then((result) => {
|
|
3004
|
+
cleanup();
|
|
3005
|
+
resolve(result);
|
|
3006
|
+
}, (error) => {
|
|
3007
|
+
cleanup();
|
|
3008
|
+
reject(error instanceof Error ? error : new RepositorySourceException({
|
|
3009
|
+
cause: error,
|
|
3010
|
+
code: "INVALID_SOURCE_DATA",
|
|
3011
|
+
operation: "read-file-page",
|
|
3012
|
+
path: null,
|
|
3013
|
+
retryable: false
|
|
3014
|
+
}));
|
|
3015
|
+
});
|
|
2801
3016
|
});
|
|
2802
3017
|
};
|
|
2803
|
-
const
|
|
3018
|
+
const readCompleteFile = async (path, options) => {
|
|
2804
3019
|
const parsedPath = parseRepositoryPath(path);
|
|
2805
3020
|
throwIfSignalAborted(options?.signal);
|
|
2806
3021
|
registerPath(parsedPath);
|
|
2807
|
-
|
|
2808
|
-
if (readPromise === void 0) {
|
|
2809
|
-
readPromise = removeFailedRead(parsedPath, loadFile(parsedPath));
|
|
2810
|
-
readCache.set(parsedPath, readPromise);
|
|
2811
|
-
}
|
|
2812
|
-
const content = await waitForRead(readPromise, options?.signal);
|
|
3022
|
+
const content = await awaitWithCancellation(loadFile(parsedPath, options?.signal), options?.signal);
|
|
2813
3023
|
throwIfSignalAborted(options?.signal);
|
|
2814
|
-
return
|
|
3024
|
+
return content.slice();
|
|
3025
|
+
};
|
|
3026
|
+
const listAdapterEntriesPage = async (options) => {
|
|
3027
|
+
const prefix = options.prefix === void 0 ? REPOSITORY_ROOT : parseRepositoryPath(options.prefix);
|
|
3028
|
+
registerPath(prefix);
|
|
3029
|
+
if (!Number.isSafeInteger(options.maxEntries) || options.maxEntries < 1 || options.maxEntries > adapterLimits.maxPageEntries) return throwResourceLimitExceeded("maxEntries");
|
|
3030
|
+
throwIfSignalAborted(options.signal);
|
|
3031
|
+
const page = await repository.listEntriesPage({
|
|
3032
|
+
...options.cursor === void 0 ? {} : { cursor: options.cursor },
|
|
3033
|
+
maxEntries: options.maxEntries,
|
|
3034
|
+
prefix,
|
|
3035
|
+
...createSourceOptions(signal, options.signal) ?? {}
|
|
3036
|
+
});
|
|
3037
|
+
throwIfSignalAborted(options.signal);
|
|
3038
|
+
if (page.snapshot.id !== repository.snapshot.id || page.entries.length > options.maxEntries || page.entries.length === 0 && !page.isComplete || (page.isComplete ? page.nextCursor !== null : page.nextCursor === null)) return invalidSourceData$3("list-entries-page", prefix);
|
|
3039
|
+
let previousPath = null;
|
|
3040
|
+
const entries = page.entries.map((candidate) => {
|
|
3041
|
+
const entry = copyReaderEntry$1(candidate, "list-entries-page", prefix);
|
|
3042
|
+
if (!isStrictDescendant(entry.path, prefix) || previousPath !== null && compareRepositoryPaths(previousPath, entry.path) >= 0) return invalidSourceData$3("list-entries-page", entry.path);
|
|
3043
|
+
previousPath = entry.path;
|
|
3044
|
+
registerPath(entry.path);
|
|
3045
|
+
return entry;
|
|
3046
|
+
});
|
|
3047
|
+
return Object.freeze({
|
|
3048
|
+
entries: Object.freeze(entries),
|
|
3049
|
+
isComplete: page.isComplete,
|
|
3050
|
+
nextCursor: page.nextCursor,
|
|
3051
|
+
snapshot: repository.snapshot
|
|
3052
|
+
});
|
|
3053
|
+
};
|
|
3054
|
+
const readAdapterFilePage = async (path, options) => {
|
|
3055
|
+
const parsedPath = parseRepositoryPath(path);
|
|
3056
|
+
if (!Number.isSafeInteger(options.offset) || options.offset < 0 || !Number.isSafeInteger(options.maxBytes) || options.maxBytes < 1 || options.maxBytes > adapterLimits.maxPageBytes) return invalidSourceData$3("read-file-page", parsedPath);
|
|
3057
|
+
throwIfSignalAborted(options.signal);
|
|
3058
|
+
registerPath(parsedPath);
|
|
3059
|
+
const reservedBytes = Math.min(options.maxBytes, limits.maxTotalBytesRead - totalBytesRead);
|
|
3060
|
+
if (reservedBytes < 1) return throwResourceLimitExceeded("maxTotalBytesRead");
|
|
3061
|
+
reserveReadBytes(reservedBytes);
|
|
3062
|
+
let page;
|
|
3063
|
+
try {
|
|
3064
|
+
page = await repository.readFilePage(parsedPath, {
|
|
3065
|
+
maxBytes: reservedBytes,
|
|
3066
|
+
offset: options.offset,
|
|
3067
|
+
...createSourceOptions(signal, options.signal) ?? {}
|
|
3068
|
+
});
|
|
3069
|
+
} catch (error) {
|
|
3070
|
+
totalBytesRead -= reservedBytes;
|
|
3071
|
+
throw error;
|
|
3072
|
+
}
|
|
3073
|
+
throwIfSignalAborted(options.signal);
|
|
3074
|
+
if (page.snapshot.id !== repository.snapshot.id || page.offset !== options.offset || !(page.bytes instanceof Uint8Array) || !Number.isSafeInteger(page.totalBytes) || page.totalBytes < 0 || page.totalBytes > limits.maxFileBytes || page.bytes.byteLength > reservedBytes || page.bytes.byteLength > page.totalBytes - page.offset || page.bytes.byteLength === 0 && !page.isComplete || (page.isComplete ? page.nextOffset !== null || page.offset + page.bytes.byteLength !== page.totalBytes : page.nextOffset !== page.offset + page.bytes.byteLength)) {
|
|
3075
|
+
totalBytesRead -= reservedBytes;
|
|
3076
|
+
return invalidSourceData$3("read-file-page", parsedPath);
|
|
3077
|
+
}
|
|
3078
|
+
totalBytesRead -= reservedBytes - page.bytes.byteLength;
|
|
3079
|
+
return Object.freeze({
|
|
3080
|
+
bytes: page.bytes.slice(),
|
|
3081
|
+
isComplete: page.isComplete,
|
|
3082
|
+
nextOffset: page.nextOffset,
|
|
3083
|
+
offset: page.offset,
|
|
3084
|
+
snapshot: repository.snapshot,
|
|
3085
|
+
totalBytes: page.totalBytes
|
|
3086
|
+
});
|
|
2815
3087
|
};
|
|
2816
|
-
const
|
|
3088
|
+
const adapterRepository = Object.freeze({
|
|
2817
3089
|
getEntry,
|
|
2818
|
-
|
|
2819
|
-
|
|
3090
|
+
limits: adapterLimits,
|
|
3091
|
+
listEntriesPage: listAdapterEntriesPage,
|
|
3092
|
+
readFilePage: readAdapterFilePage,
|
|
3093
|
+
snapshot: repository.snapshot
|
|
2820
3094
|
});
|
|
2821
3095
|
return Object.freeze({
|
|
2822
|
-
|
|
3096
|
+
adapterRepository,
|
|
3097
|
+
reader: Object.freeze({
|
|
3098
|
+
getEntry,
|
|
3099
|
+
iterateEntries,
|
|
3100
|
+
readCompleteFile
|
|
3101
|
+
}),
|
|
2823
3102
|
throwIfAborted: throwIfSignalAborted
|
|
2824
3103
|
});
|
|
2825
3104
|
};
|
|
@@ -2845,7 +3124,7 @@ var findNonblankLine = (lines, startIndex) => {
|
|
|
2845
3124
|
* - RESOURCE_LIMIT_EXCEEDED: The repository-level diagnostic budget was exceeded.
|
|
2846
3125
|
*/
|
|
2847
3126
|
var validateAgentDescription = (asset, agentId, kind, limits) => {
|
|
2848
|
-
const diagnostics = createCoreDiagnosticCollector(limits, "
|
|
3127
|
+
const diagnostics = createCoreDiagnosticCollector(limits, "validate-project");
|
|
2849
3128
|
const value = trimRepositoryFormatWhitespace(asset.content);
|
|
2850
3129
|
const scalarLength = countUnicodeScalars$1(value);
|
|
2851
3130
|
const code = kind === "description" ? "MOLDEA_AGENT_DESCRIPTION_INVALID" : "MOLDEA_AGENT_HANDOFF_DESCRIPTION_INVALID";
|
|
@@ -2888,7 +3167,7 @@ var validateAgentDescription = (asset, agentId, kind, limits) => {
|
|
|
2888
3167
|
* - RESOURCE_LIMIT_EXCEEDED: The repository-level diagnostic budget was exceeded.
|
|
2889
3168
|
*/
|
|
2890
3169
|
var validateAgentInstruction = (asset, agentId, limits) => {
|
|
2891
|
-
const diagnostics = createCoreDiagnosticCollector(limits, "
|
|
3170
|
+
const diagnostics = createCoreDiagnosticCollector(limits, "validate-project");
|
|
2892
3171
|
if (!hasNonWhitespace(asset.content)) {
|
|
2893
3172
|
diagnostics.add({
|
|
2894
3173
|
code: "MOLDEA_AGENT_INSTRUCTION_EMPTY",
|
|
@@ -2924,7 +3203,7 @@ var validateAgentInstruction = (asset, agentId, limits) => {
|
|
|
2924
3203
|
var invalidSourceData$2 = (path) => {
|
|
2925
3204
|
throw new RepositorySourceException({
|
|
2926
3205
|
code: "INVALID_SOURCE_DATA",
|
|
2927
|
-
operation: "read-file",
|
|
3206
|
+
operation: "read-file-page",
|
|
2928
3207
|
path,
|
|
2929
3208
|
retryable: false
|
|
2930
3209
|
});
|
|
@@ -2947,12 +3226,12 @@ var invalidSourceData$2 = (path) => {
|
|
|
2947
3226
|
* - ABORTED: Repository inspection or the repository read was aborted.
|
|
2948
3227
|
*/
|
|
2949
3228
|
var readRepositoryTextAsset = async (repository, path, limits, signal) => {
|
|
2950
|
-
const content = await repository.
|
|
3229
|
+
const content = await repository.readCompleteFile(path, signal === void 0 ? void 0 : { signal });
|
|
2951
3230
|
if (!(content instanceof Uint8Array)) return invalidSourceData$2(path);
|
|
2952
3231
|
const normalized = normalizeTextDocument({
|
|
2953
3232
|
content,
|
|
2954
3233
|
path
|
|
2955
|
-
}, limits, "
|
|
3234
|
+
}, limits, "validate-project");
|
|
2956
3235
|
if (!normalized.valid || normalized.text === null) return freezeRecursively({
|
|
2957
3236
|
asset: null,
|
|
2958
3237
|
diagnostics: normalized.diagnostics,
|
|
@@ -3025,7 +3304,7 @@ var recordOccurrence = (occurrences, variableId, range) => {
|
|
|
3025
3304
|
* - RESOURCE_LIMIT_EXCEEDED: The repository-level diagnostic budget was exceeded.
|
|
3026
3305
|
*/
|
|
3027
3306
|
var validateRuntimePlaceholders = (manifestPath, agentId, instruction, declaredVariables, limits) => {
|
|
3028
|
-
const collector = createCoreDiagnosticCollector(limits, "
|
|
3307
|
+
const collector = createCoreDiagnosticCollector(limits, "validate-project");
|
|
3029
3308
|
const locator = createSourceLocator(instruction.content);
|
|
3030
3309
|
const occurrences = /* @__PURE__ */ new Map();
|
|
3031
3310
|
let cursor = 0;
|
|
@@ -3182,7 +3461,7 @@ var readInstruction = async (repository, path, agentId, declaration, options, co
|
|
|
3182
3461
|
*/
|
|
3183
3462
|
var inspectAgentAssets = async (repository, manifest, discovery, options, signal) => {
|
|
3184
3463
|
options = createCoreOperationOptionsSnapshot(options);
|
|
3185
|
-
const collector = createCoreDiagnosticCollector(options.limits, "
|
|
3464
|
+
const collector = createCoreDiagnosticCollector(options.limits, "validate-project");
|
|
3186
3465
|
const agents = [];
|
|
3187
3466
|
const registeredAgents = manifest.agents ?? {};
|
|
3188
3467
|
const registeredIds = new Set(Object.keys(registeredAgents));
|
|
@@ -3354,11 +3633,16 @@ var copyReaderEntry = (candidate, operation, expectedPath) => {
|
|
|
3354
3633
|
const record = candidate;
|
|
3355
3634
|
const pathCandidate = record["path"];
|
|
3356
3635
|
const typeCandidate = record["type"];
|
|
3636
|
+
const byteLength = record["byteLength"];
|
|
3637
|
+
const contentIdentity = record["contentIdentity"];
|
|
3357
3638
|
if (typeof pathCandidate !== "string" || !isRepositoryPath(pathCandidate)) return invalidSourceData$1(operation, expectedPath ?? null);
|
|
3358
3639
|
const path = parseRepositoryPath(pathCandidate);
|
|
3359
3640
|
if (expectedPath !== void 0 && path !== expectedPath) return invalidSourceData$1(operation, path);
|
|
3360
3641
|
if (typeCandidate !== "file" && typeCandidate !== "directory" && typeCandidate !== "symlink") return invalidSourceData$1(operation, path);
|
|
3642
|
+
if (typeCandidate === "file" ? !Number.isSafeInteger(byteLength) || byteLength < 0 || contentIdentity !== null && typeof contentIdentity !== "string" : byteLength !== null || contentIdentity !== null) return invalidSourceData$1(operation, path);
|
|
3361
3643
|
return {
|
|
3644
|
+
byteLength,
|
|
3645
|
+
contentIdentity,
|
|
3362
3646
|
path,
|
|
3363
3647
|
type: typeCandidate
|
|
3364
3648
|
};
|
|
@@ -3408,7 +3692,7 @@ var retainCanonicalFile = (inventory, path, fileKind, agentId) => {
|
|
|
3408
3692
|
inventory.runtimeGuidance.add(path);
|
|
3409
3693
|
return;
|
|
3410
3694
|
}
|
|
3411
|
-
if (agentId === null) return invalidSourceData$1("list-entries", path);
|
|
3695
|
+
if (agentId === null) return invalidSourceData$1("list-entries-page", path);
|
|
3412
3696
|
const agent = getAgent(inventory.agents, agentId);
|
|
3413
3697
|
if (fileKind === "agent-description") agent.description = path;
|
|
3414
3698
|
else if (fileKind === "agent-instruction") agent.instruction = path;
|
|
@@ -3458,7 +3742,7 @@ var retainFoundationEntry = (entry, expectedPath, missingCode, working, diagnost
|
|
|
3458
3742
|
addEntryTypeDiagnostic(diagnostics, entry, "file");
|
|
3459
3743
|
};
|
|
3460
3744
|
var checkFoundationListing = (listedEntry, exactEntry) => {
|
|
3461
|
-
if (exactEntry === null || exactEntry.type !== listedEntry.type) return invalidSourceData$1("list-entries", listedEntry.path);
|
|
3745
|
+
if (exactEntry === null || exactEntry.type !== listedEntry.type) return invalidSourceData$1("list-entries-page", listedEntry.path);
|
|
3462
3746
|
};
|
|
3463
3747
|
/**
|
|
3464
3748
|
* Discovers and classifies version 1 canonical assets through one repository snapshot.
|
|
@@ -3478,7 +3762,7 @@ var checkFoundationListing = (listedEntry, exactEntry) => {
|
|
|
3478
3762
|
* - ABORTED: Discovery or a repository operation was aborted.
|
|
3479
3763
|
*/
|
|
3480
3764
|
var discoverCanonicalAssets = async (repository, limits, signal, foundations) => {
|
|
3481
|
-
const diagnostics = createCoreDiagnosticCollector(limits, "
|
|
3765
|
+
const diagnostics = createCoreDiagnosticCollector(limits, "validate-project");
|
|
3482
3766
|
const working = createWorkingInventory();
|
|
3483
3767
|
const moldeaEntry = foundations === void 0 ? await readExactEntry(repository, MOLDEA_ROOT$1, signal) : foundations.moldeaRoot;
|
|
3484
3768
|
if (moldeaEntry === null) {
|
|
@@ -3507,10 +3791,10 @@ var discoverCanonicalAssets = async (repository, limits, signal, foundations) =>
|
|
|
3507
3791
|
prefix: MOLDEA_ROOT$1,
|
|
3508
3792
|
signal
|
|
3509
3793
|
};
|
|
3510
|
-
for await (const candidate of repository.
|
|
3511
|
-
const entry = copyReaderEntry(candidate, "list-entries");
|
|
3512
|
-
if (!entry.path.startsWith("/moldea/")) return invalidSourceData$1("list-entries", entry.path);
|
|
3513
|
-
if (seenPaths.has(entry.path)) return invalidSourceData$1("list-entries", entry.path);
|
|
3794
|
+
for await (const candidate of repository.iterateEntries(listOptions)) {
|
|
3795
|
+
const entry = copyReaderEntry(candidate, "list-entries-page");
|
|
3796
|
+
if (!entry.path.startsWith("/moldea/")) return invalidSourceData$1("list-entries-page", entry.path);
|
|
3797
|
+
if (seenPaths.has(entry.path)) return invalidSourceData$1("list-entries-page", entry.path);
|
|
3514
3798
|
seenPaths.add(entry.path);
|
|
3515
3799
|
if (entry.path === MANIFEST_PATH$1) {
|
|
3516
3800
|
checkFoundationListing(entry, manifestEntry);
|
|
@@ -3546,8 +3830,8 @@ var discoverCanonicalAssets = async (repository, limits, signal, foundations) =>
|
|
|
3546
3830
|
});
|
|
3547
3831
|
}
|
|
3548
3832
|
}
|
|
3549
|
-
if (manifestEntry !== null !== listedManifest) return invalidSourceData$1("list-entries", MANIFEST_PATH$1);
|
|
3550
|
-
if (projectEntry !== null !== listedProject) return invalidSourceData$1("list-entries", PROJECT_PATH$1);
|
|
3833
|
+
if (manifestEntry !== null !== listedManifest) return invalidSourceData$1("list-entries-page", MANIFEST_PATH$1);
|
|
3834
|
+
if (projectEntry !== null !== listedProject) return invalidSourceData$1("list-entries-page", PROJECT_PATH$1);
|
|
3551
3835
|
return finalizeResult(working, diagnostics);
|
|
3552
3836
|
};
|
|
3553
3837
|
//#endregion
|
|
@@ -3732,7 +4016,7 @@ var collectCycleDiagnostics = (index, diagnostics) => {
|
|
|
3732
4016
|
* - RESOURCE_LIMIT_EXCEEDED: The repository-level diagnostic budget was exceeded.
|
|
3733
4017
|
*/
|
|
3734
4018
|
var validateDecisionGraph = (candidates, limits) => {
|
|
3735
|
-
const diagnostics = createCoreDiagnosticCollector(limits, "
|
|
4019
|
+
const diagnostics = createCoreDiagnosticCollector(limits, "validate-project");
|
|
3736
4020
|
const index = buildGraphIndex(candidates);
|
|
3737
4021
|
collectDuplicateDiagnostics(index, diagnostics);
|
|
3738
4022
|
collectReferenceDiagnostics(index, diagnostics);
|
|
@@ -3745,7 +4029,7 @@ var validateDecisionGraph = (candidates, limits) => {
|
|
|
3745
4029
|
var invalidSourceData = (path) => {
|
|
3746
4030
|
throw new RepositorySourceException({
|
|
3747
4031
|
code: "INVALID_SOURCE_DATA",
|
|
3748
|
-
operation: "read-file",
|
|
4032
|
+
operation: "read-file-page",
|
|
3749
4033
|
path,
|
|
3750
4034
|
retryable: false
|
|
3751
4035
|
});
|
|
@@ -3774,17 +4058,17 @@ var sortDecisions = (decisions) => {
|
|
|
3774
4058
|
*/
|
|
3775
4059
|
var readDecisionGraph = async (repository, paths, options, signal) => {
|
|
3776
4060
|
options = createCoreOperationOptionsSnapshot(options);
|
|
3777
|
-
const diagnostics = createCoreDiagnosticCollector(options.limits, "
|
|
4061
|
+
const diagnostics = createCoreDiagnosticCollector(options.limits, "validate-project");
|
|
3778
4062
|
const candidates = [];
|
|
3779
4063
|
const decisions = [];
|
|
3780
4064
|
const readOptions = signal === void 0 ? void 0 : { signal };
|
|
3781
4065
|
for (const path of [...paths].sort(compareExactStrings)) {
|
|
3782
|
-
const content = await repository.
|
|
4066
|
+
const content = await repository.readCompleteFile(path, readOptions);
|
|
3783
4067
|
if (!(content instanceof Uint8Array)) return invalidSourceData(path);
|
|
3784
4068
|
const parsed = await parseDecisionDocument({
|
|
3785
4069
|
content: content.slice(),
|
|
3786
4070
|
path
|
|
3787
|
-
}, options, "
|
|
4071
|
+
}, options, "validate-project");
|
|
3788
4072
|
for (const diagnostic of parsed.diagnostics) diagnostics.merge(diagnostic);
|
|
3789
4073
|
candidates.push({
|
|
3790
4074
|
decision: parsed.decision,
|
|
@@ -3860,7 +4144,7 @@ var validateDecisionRelationship = (referencedPath, pointer, context, agentId) =
|
|
|
3860
4144
|
* - RESOURCE_LIMIT_EXCEEDED: The repository-level diagnostic budget was exceeded.
|
|
3861
4145
|
*/
|
|
3862
4146
|
var validateManifestRelationships = (manifestPath, manifest, discovery, decisions, limits) => {
|
|
3863
|
-
const collector = createCoreDiagnosticCollector(limits, "
|
|
4147
|
+
const collector = createCoreDiagnosticCollector(limits, "validate-project");
|
|
3864
4148
|
const validAgentContextPaths = new Set(discovery.inventory.context);
|
|
3865
4149
|
const validTopLevelContextPaths = new Set(validAgentContextPaths);
|
|
3866
4150
|
if (discovery.inventory.project !== null) validTopLevelContextPaths.add(discovery.inventory.project);
|
|
@@ -3925,9 +4209,11 @@ var inspectMirror = async (repository, manifestPath, canonicalInstruction, mirro
|
|
|
3925
4209
|
return null;
|
|
3926
4210
|
}
|
|
3927
4211
|
return {
|
|
4212
|
+
byteLength: mirrorResult.asset.utf8ByteLength,
|
|
3928
4213
|
canonicalDigest: canonicalInstruction.digest,
|
|
3929
4214
|
digest: mirrorResult.asset.digest,
|
|
3930
|
-
path: mirrorPath
|
|
4215
|
+
path: mirrorPath,
|
|
4216
|
+
scalarLength: mirrorResult.asset.scalarLength
|
|
3931
4217
|
};
|
|
3932
4218
|
};
|
|
3933
4219
|
/**
|
|
@@ -3951,7 +4237,7 @@ var inspectMirror = async (repository, manifestPath, canonicalInstruction, mirro
|
|
|
3951
4237
|
*/
|
|
3952
4238
|
var inspectMirrors = async (repository, manifestPath, agents, options, signal) => {
|
|
3953
4239
|
options = createCoreOperationOptionsSnapshot(options);
|
|
3954
|
-
const collector = createCoreDiagnosticCollector(options.limits, "
|
|
4240
|
+
const collector = createCoreDiagnosticCollector(options.limits, "validate-project");
|
|
3955
4241
|
const agentMirrors = [];
|
|
3956
4242
|
const operationOptions = signal === void 0 ? void 0 : { signal };
|
|
3957
4243
|
for (const agent of [...agents].sort((left, right) => compareExactStrings(left.id, right.id))) {
|
|
@@ -3999,7 +4285,7 @@ var addDiagnostics$2 = (collector, diagnostics) => {
|
|
|
3999
4285
|
*/
|
|
4000
4286
|
var readProjectFile = async (repository, path, options, signal) => {
|
|
4001
4287
|
options = createCoreOperationOptionsSnapshot(options);
|
|
4002
|
-
const collector = createCoreDiagnosticCollector(options.limits, "
|
|
4288
|
+
const collector = createCoreDiagnosticCollector(options.limits, "validate-project");
|
|
4003
4289
|
let project = null;
|
|
4004
4290
|
if (path !== null) {
|
|
4005
4291
|
const result = await readRepositoryTextAsset(repository, path, options.limits, signal);
|
|
@@ -4040,7 +4326,7 @@ var readProjectFile = async (repository, path, options, signal) => {
|
|
|
4040
4326
|
*/
|
|
4041
4327
|
var readProjectAssets = async (repository, manifest, discovery, options, signal, projectFile) => {
|
|
4042
4328
|
options = createCoreOperationOptionsSnapshot(options);
|
|
4043
|
-
const collector = createCoreDiagnosticCollector(options.limits, "
|
|
4329
|
+
const collector = createCoreDiagnosticCollector(options.limits, "validate-project");
|
|
4044
4330
|
const context = [];
|
|
4045
4331
|
const inspectedProject = projectFile ?? await readProjectFile(repository, discovery.inventory.project, options, signal);
|
|
4046
4332
|
addDiagnostics$2(collector, inspectedProject.diagnostics);
|
|
@@ -4307,7 +4593,7 @@ var validateCandidate = (candidate, entry, manifestPath, collector) => {
|
|
|
4307
4593
|
* - ABORTED: Repository inspection or a repository lookup was aborted.
|
|
4308
4594
|
*/
|
|
4309
4595
|
var validateRepositoryReferences = async (repository, manifestPath, manifest, discovery, limits, signal) => {
|
|
4310
|
-
const collector = createCoreDiagnosticCollector(limits, "
|
|
4596
|
+
const collector = createCoreDiagnosticCollector(limits, "validate-project");
|
|
4311
4597
|
const blockedPaths = new Set(discovery.diagnostics.flatMap((diagnostic) => diagnostic.path === null ? [] : [diagnostic.path]));
|
|
4312
4598
|
const entryCache = /* @__PURE__ */ new Map();
|
|
4313
4599
|
const operationOptions = signal === void 0 ? void 0 : { signal };
|
|
@@ -4358,7 +4644,7 @@ var isBlockedPath = (path, blockedPaths) => {
|
|
|
4358
4644
|
*/
|
|
4359
4645
|
var readRuntimeGuidance = async (repository, manifestPath, manifest, discovery, options, signal) => {
|
|
4360
4646
|
options = createCoreOperationOptionsSnapshot(options);
|
|
4361
|
-
const collector = createCoreDiagnosticCollector(options.limits, "
|
|
4647
|
+
const collector = createCoreDiagnosticCollector(options.limits, "validate-project");
|
|
4362
4648
|
const runtimes = [];
|
|
4363
4649
|
const discoveredPaths = new Set(discovery.inventory.runtimeGuidance);
|
|
4364
4650
|
const blockedPaths = new Set(discovery.diagnostics.flatMap((diagnostic) => diagnostic.path === null ? [] : [diagnostic.path]));
|
|
@@ -4421,7 +4707,7 @@ var addDiagnostics = (collector, diagnostics) => {
|
|
|
4421
4707
|
var inspectUniversalProject = async (context, options) => {
|
|
4422
4708
|
options = createCoreOperationOptionsSnapshot(options);
|
|
4423
4709
|
const { session, signal } = context;
|
|
4424
|
-
const collector = createCoreDiagnosticCollector(options.limits, "
|
|
4710
|
+
const collector = createCoreDiagnosticCollector(options.limits, "validate-project");
|
|
4425
4711
|
const operationOptions = signal === void 0 ? void 0 : { signal };
|
|
4426
4712
|
const moldeaRoot = await session.reader.getEntry(MOLDEA_ROOT, operationOptions);
|
|
4427
4713
|
let manifestEntry = null;
|
|
@@ -4433,9 +4719,9 @@ var inspectUniversalProject = async (context, options) => {
|
|
|
4433
4719
|
manifestEntry = await session.reader.getEntry(MANIFEST_PATH, operationOptions);
|
|
4434
4720
|
if (manifestEntry?.type === "file") {
|
|
4435
4721
|
const parsedManifest = await inspectManifestDocument({
|
|
4436
|
-
content: await session.reader.
|
|
4722
|
+
content: await session.reader.readCompleteFile(MANIFEST_PATH, operationOptions),
|
|
4437
4723
|
path: MANIFEST_PATH
|
|
4438
|
-
}, options, "
|
|
4724
|
+
}, options, "validate-project");
|
|
4439
4725
|
formatVersion = parsedManifest.formatVersion;
|
|
4440
4726
|
runtimeLocations = parsedManifest.runtimeLocations;
|
|
4441
4727
|
addDiagnostics(collector, parsedManifest.diagnostics);
|
|
@@ -4493,35 +4779,35 @@ var inspectUniversalProject = async (context, options) => {
|
|
|
4493
4779
|
});
|
|
4494
4780
|
};
|
|
4495
4781
|
//#endregion
|
|
4496
|
-
//#region src/project-
|
|
4782
|
+
//#region src/project-validation/index.ts
|
|
4497
4783
|
var isRecord$1 = (candidate) => {
|
|
4498
4784
|
return typeof candidate === "object" && candidate !== null && !Array.isArray(candidate);
|
|
4499
4785
|
};
|
|
4500
|
-
var invalidArgument$
|
|
4786
|
+
var invalidArgument$2 = () => {
|
|
4501
4787
|
throw new CoreOperationException({
|
|
4502
4788
|
code: "INVALID_ARGUMENT",
|
|
4503
|
-
operation: "
|
|
4789
|
+
operation: "validate-project"
|
|
4504
4790
|
});
|
|
4505
4791
|
};
|
|
4506
4792
|
var isRepositoryReader = (candidate) => {
|
|
4507
|
-
return isRecord$1(candidate) && typeof candidate["getEntry"] === "function" && typeof candidate["
|
|
4793
|
+
return isRecord$1(candidate) && isRecord$1(candidate["snapshot"]) && typeof candidate["snapshot"]["id"] === "string" && typeof candidate["snapshot"]["sourceKind"] === "string" && typeof candidate["compare"] === "function" && typeof candidate["getEntry"] === "function" && typeof candidate["listEntriesPage"] === "function" && typeof candidate["readFilePage"] === "function";
|
|
4508
4794
|
};
|
|
4509
4795
|
var isAbortSignal = (candidate) => {
|
|
4510
4796
|
return isRecord$1(candidate) && typeof candidate["aborted"] === "boolean" && typeof candidate["addEventListener"] === "function" && typeof candidate["removeEventListener"] === "function";
|
|
4511
4797
|
};
|
|
4512
4798
|
var validateInput = (candidate) => {
|
|
4513
4799
|
try {
|
|
4514
|
-
if (!isRecord$1(candidate)) return invalidArgument$
|
|
4800
|
+
if (!isRecord$1(candidate)) return invalidArgument$2();
|
|
4515
4801
|
const repository = candidate["repository"];
|
|
4516
4802
|
const signal = candidate["signal"];
|
|
4517
|
-
if (!isRepositoryReader(repository) || signal !== void 0 && !isAbortSignal(signal)) return invalidArgument$
|
|
4803
|
+
if (Reflect.ownKeys(candidate).some((key) => key !== "repository" && key !== "signal") || !isRepositoryReader(repository) || signal !== void 0 && !isAbortSignal(signal)) return invalidArgument$2();
|
|
4518
4804
|
return {
|
|
4519
4805
|
repository,
|
|
4520
4806
|
...signal === void 0 ? {} : { signal }
|
|
4521
4807
|
};
|
|
4522
4808
|
} catch (error) {
|
|
4523
4809
|
if (error instanceof CoreOperationException) throw error;
|
|
4524
|
-
return invalidArgument$
|
|
4810
|
+
return invalidArgument$2();
|
|
4525
4811
|
}
|
|
4526
4812
|
};
|
|
4527
4813
|
/**
|
|
@@ -4543,7 +4829,7 @@ var validateInput = (candidate) => {
|
|
|
4543
4829
|
* - ABORTED: Project inspection or a repository operation was aborted.
|
|
4544
4830
|
* - ADAPTER_EXECUTION_FAILED: A runtime adapter failed or returned an invalid result.
|
|
4545
4831
|
*/
|
|
4546
|
-
var
|
|
4832
|
+
var validateProjectState = async (input, options) => {
|
|
4547
4833
|
const validatedInput = validateInput(input);
|
|
4548
4834
|
const operationOptions = createCoreOperationOptionsSnapshot(options);
|
|
4549
4835
|
const session = createRepositoryInspectionSession(validatedInput.repository, operationOptions.limits, validatedInput.signal);
|
|
@@ -4552,28 +4838,200 @@ var inspectProject = async (input, options) => {
|
|
|
4552
4838
|
...validatedInput.signal === void 0 ? {} : { signal: validatedInput.signal }
|
|
4553
4839
|
}, operationOptions);
|
|
4554
4840
|
if (universal.project === null) return freezeRecursively({
|
|
4555
|
-
diagnostics: universal.diagnostics,
|
|
4556
|
-
evidence: [],
|
|
4557
|
-
formatVersion: universal.formatVersion,
|
|
4558
4841
|
project: null,
|
|
4559
|
-
|
|
4842
|
+
result: {
|
|
4843
|
+
diagnostics: universal.diagnostics,
|
|
4844
|
+
evidence: [],
|
|
4845
|
+
formatVersion: universal.formatVersion,
|
|
4846
|
+
source: validatedInput.repository.snapshot,
|
|
4847
|
+
summary: null,
|
|
4848
|
+
valid: false
|
|
4849
|
+
}
|
|
4560
4850
|
});
|
|
4851
|
+
const projectSummary = createProjectSummary(universal.project);
|
|
4561
4852
|
const availabilityDiagnostics = validateRuntimeAdapterAvailability(universal.runtimeLocations, universal.project.formatVersion, operationOptions);
|
|
4562
4853
|
if (availabilityDiagnostics.length > 0) return freezeRecursively({
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4854
|
+
project: universal.project,
|
|
4855
|
+
result: {
|
|
4856
|
+
diagnostics: availabilityDiagnostics,
|
|
4857
|
+
evidence: [],
|
|
4858
|
+
formatVersion: universal.formatVersion,
|
|
4859
|
+
source: validatedInput.repository.snapshot,
|
|
4860
|
+
summary: projectSummary,
|
|
4861
|
+
valid: false
|
|
4862
|
+
}
|
|
4568
4863
|
});
|
|
4569
4864
|
const adapterInspection = await inspectRuntimeAdapters(universal.project, session, operationOptions, validatedInput.signal);
|
|
4570
4865
|
const valid = adapterInspection.diagnostics.length === 0;
|
|
4571
4866
|
return freezeRecursively({
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4867
|
+
project: universal.project,
|
|
4868
|
+
result: {
|
|
4869
|
+
diagnostics: adapterInspection.diagnostics,
|
|
4870
|
+
evidence: adapterInspection.evidence,
|
|
4871
|
+
formatVersion: universal.formatVersion,
|
|
4872
|
+
source: validatedInput.repository.snapshot,
|
|
4873
|
+
summary: projectSummary,
|
|
4874
|
+
valid
|
|
4875
|
+
}
|
|
4876
|
+
});
|
|
4877
|
+
};
|
|
4878
|
+
/** Validates one project without returning canonical document bodies. */
|
|
4879
|
+
var validateProject = async (input, options) => (await validateProjectState(input, options)).result;
|
|
4880
|
+
//#endregion
|
|
4881
|
+
//#region src/project-inspection-page/index.ts
|
|
4882
|
+
var CURSOR_PREFIX = "core3";
|
|
4883
|
+
var encoder = new TextEncoder();
|
|
4884
|
+
var invalidArgument$1 = () => {
|
|
4885
|
+
throw new CoreOperationException({
|
|
4886
|
+
code: "INVALID_ARGUMENT",
|
|
4887
|
+
operation: "inspect-project-page"
|
|
4888
|
+
});
|
|
4889
|
+
};
|
|
4890
|
+
/** Serializes the closed inspection records with recursively sorted object keys. */
|
|
4891
|
+
var serializeDeterministically = (candidate) => {
|
|
4892
|
+
if (candidate === null || typeof candidate !== "object") {
|
|
4893
|
+
const serialized = JSON.stringify(candidate);
|
|
4894
|
+
return serialized === void 0 ? "null" : serialized;
|
|
4895
|
+
}
|
|
4896
|
+
if (Array.isArray(candidate)) return `[${candidate.map((item) => serializeDeterministically(item)).join(",")}]`;
|
|
4897
|
+
return `{${Object.entries(candidate).filter(([, value]) => value !== void 0).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, value]) => `${JSON.stringify(key)}:${serializeDeterministically(value)}`).join(",")}}`;
|
|
4898
|
+
};
|
|
4899
|
+
var createIdentity = (parts) => createRepositoryIdentity(parts.map((part) => encoder.encode(part)));
|
|
4900
|
+
var createItemBaseKey = (item) => {
|
|
4901
|
+
if (item.kind === "metadata") return [
|
|
4902
|
+
"0",
|
|
4903
|
+
item.metadata.path,
|
|
4904
|
+
item.metadata.kind,
|
|
4905
|
+
item.metadata.agentId ?? "",
|
|
4906
|
+
item.metadata.decisionId ?? "",
|
|
4907
|
+
item.metadata.digest
|
|
4908
|
+
].join(":");
|
|
4909
|
+
if (item.kind === "diagnostic") return [
|
|
4910
|
+
"1",
|
|
4911
|
+
item.diagnostic.source,
|
|
4912
|
+
item.diagnostic.code,
|
|
4913
|
+
item.diagnostic.path ?? "",
|
|
4914
|
+
createIdentity([serializeDeterministically(item.diagnostic)])
|
|
4915
|
+
].join(":");
|
|
4916
|
+
return [
|
|
4917
|
+
"2",
|
|
4918
|
+
item.evidence.source,
|
|
4919
|
+
item.evidence.kind,
|
|
4920
|
+
item.evidence.agentId ?? "",
|
|
4921
|
+
createIdentity([serializeDeterministically(item.evidence)])
|
|
4922
|
+
].join(":");
|
|
4923
|
+
};
|
|
4924
|
+
/** Assigns stable unique keys without relying on collection offsets. */
|
|
4925
|
+
var createKeyedItems = (items) => {
|
|
4926
|
+
const sorted = items.map((item) => ({
|
|
4927
|
+
baseKey: createItemBaseKey(item),
|
|
4928
|
+
item
|
|
4929
|
+
})).sort((left, right) => left.baseKey < right.baseKey ? -1 : left.baseKey > right.baseKey ? 1 : 0);
|
|
4930
|
+
const occurrences = /* @__PURE__ */ new Map();
|
|
4931
|
+
return sorted.map(({ baseKey, item }) => {
|
|
4932
|
+
const occurrence = occurrences.get(baseKey) ?? 0;
|
|
4933
|
+
occurrences.set(baseKey, occurrence + 1);
|
|
4934
|
+
return {
|
|
4935
|
+
item,
|
|
4936
|
+
key: `${baseKey}:${String(occurrence).padStart(10, "0")}`
|
|
4937
|
+
};
|
|
4938
|
+
});
|
|
4939
|
+
};
|
|
4940
|
+
var createCursorChecksum = (inspectionDigest, lastKey, view) => createIdentity([
|
|
4941
|
+
CURSOR_PREFIX,
|
|
4942
|
+
inspectionDigest,
|
|
4943
|
+
lastKey,
|
|
4944
|
+
view
|
|
4945
|
+
]);
|
|
4946
|
+
var encodeCursor = (inspectionDigest, view, lastKey) => [
|
|
4947
|
+
CURSOR_PREFIX,
|
|
4948
|
+
view,
|
|
4949
|
+
encodeURIComponent(lastKey),
|
|
4950
|
+
inspectionDigest,
|
|
4951
|
+
createCursorChecksum(inspectionDigest, lastKey, view)
|
|
4952
|
+
].join(":");
|
|
4953
|
+
var decodeCursor = (cursor, inspectionDigest, view) => {
|
|
4954
|
+
if (cursor === void 0) return null;
|
|
4955
|
+
const match = /^core3:(all|diagnostics|evidence|metadata):([^:]+):(sha256:[0-9a-f]{64}):(sha256:[0-9a-f]{64})$/u.exec(cursor);
|
|
4956
|
+
if (match === null || match[1] !== view || match[3] !== inspectionDigest) return invalidArgument$1();
|
|
4957
|
+
let lastKey;
|
|
4958
|
+
try {
|
|
4959
|
+
lastKey = decodeURIComponent(match[2]);
|
|
4960
|
+
} catch {
|
|
4961
|
+
return invalidArgument$1();
|
|
4962
|
+
}
|
|
4963
|
+
if (lastKey.length === 0 || match[4] !== createCursorChecksum(inspectionDigest, lastKey, view)) return invalidArgument$1();
|
|
4964
|
+
return lastKey;
|
|
4965
|
+
};
|
|
4966
|
+
var selectViewItems = (items, view) => view === "all" ? items : items.filter(({ item }) => {
|
|
4967
|
+
if (view === "diagnostics") return item.kind === "diagnostic";
|
|
4968
|
+
return item.kind === view;
|
|
4969
|
+
});
|
|
4970
|
+
/** Returns one bounded content-free view over a completely validated project snapshot. */
|
|
4971
|
+
var inspectProjectPage = async (input, options) => {
|
|
4972
|
+
if (typeof input !== "object" || input === null || Reflect.ownKeys(input).some((key) => key !== "cursor" && key !== "maxItems" && key !== "repository" && key !== "signal" && key !== "view") || !Number.isSafeInteger(input.maxItems) || input.maxItems < 1 || input.maxItems > options.limits.maxEntries || input.cursor !== void 0 && typeof input.cursor !== "string" || input.view !== "all" && input.view !== "diagnostics" && input.view !== "evidence" && input.view !== "metadata") return invalidArgument$1();
|
|
4973
|
+
const state = await validateProjectState({
|
|
4974
|
+
repository: input.repository,
|
|
4975
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
4976
|
+
}, options);
|
|
4977
|
+
const metadata = state.project === null ? [] : collectProjectMetadata(state.project);
|
|
4978
|
+
const allItems = createKeyedItems([
|
|
4979
|
+
...metadata.map((metadataItem) => ({
|
|
4980
|
+
kind: "metadata",
|
|
4981
|
+
metadata: metadataItem
|
|
4982
|
+
})),
|
|
4983
|
+
...state.result.diagnostics.map((diagnostic) => ({
|
|
4984
|
+
diagnostic,
|
|
4985
|
+
kind: "diagnostic"
|
|
4986
|
+
})),
|
|
4987
|
+
...state.result.evidence.map((evidence) => ({
|
|
4988
|
+
evidence,
|
|
4989
|
+
kind: "evidence"
|
|
4990
|
+
}))
|
|
4991
|
+
]);
|
|
4992
|
+
const counts = {
|
|
4993
|
+
agents: state.result.summary?.counts.agents ?? 0,
|
|
4994
|
+
context: state.result.summary?.counts.context ?? 0,
|
|
4995
|
+
decisions: state.result.summary?.counts.decisions ?? 0,
|
|
4996
|
+
diagnostics: state.result.diagnostics.length,
|
|
4997
|
+
evidence: state.result.evidence.length,
|
|
4998
|
+
metadata: metadata.length,
|
|
4999
|
+
mirrors: state.result.summary?.counts.mirrors ?? 0,
|
|
5000
|
+
runtimes: state.result.summary?.counts.runtimes ?? 0,
|
|
5001
|
+
unresolved: state.result.summary?.counts.unresolved ?? 0
|
|
5002
|
+
};
|
|
5003
|
+
const inspectionDigest = createIdentity([serializeDeterministically({
|
|
5004
|
+
counts,
|
|
5005
|
+
formatVersion: state.result.formatVersion,
|
|
5006
|
+
itemKeys: allItems.map(({ key }) => key),
|
|
5007
|
+
summary: state.result.summary,
|
|
5008
|
+
valid: state.result.valid
|
|
5009
|
+
})]);
|
|
5010
|
+
const items = selectViewItems(allItems, input.view);
|
|
5011
|
+
const lastKey = decodeCursor(input.cursor, inspectionDigest, input.view);
|
|
5012
|
+
const startIndex = lastKey === null ? 0 : items.findIndex(({ key }) => key === lastKey) + 1;
|
|
5013
|
+
if (lastKey !== null && startIndex === 0) return invalidArgument$1();
|
|
5014
|
+
const records = items.slice(startIndex, startIndex + input.maxItems).map(({ item, key }, index) => {
|
|
5015
|
+
return {
|
|
5016
|
+
item,
|
|
5017
|
+
nextCursor: startIndex + index + 1 >= items.length ? null : encodeCursor(inspectionDigest, input.view, key)
|
|
5018
|
+
};
|
|
5019
|
+
});
|
|
5020
|
+
const nextCursor = records.at(-1)?.nextCursor ?? null;
|
|
5021
|
+
return freezeRecursively({
|
|
5022
|
+
counts,
|
|
5023
|
+
formatVersion: state.result.formatVersion,
|
|
5024
|
+
inspectionDigest,
|
|
5025
|
+
page: {
|
|
5026
|
+
isComplete: nextCursor === null,
|
|
5027
|
+
nextCursor,
|
|
5028
|
+
records,
|
|
5029
|
+
totalItems: items.length
|
|
5030
|
+
},
|
|
5031
|
+
source: state.result.source,
|
|
5032
|
+
summary: state.result.summary,
|
|
5033
|
+
valid: state.result.valid,
|
|
5034
|
+
view: input.view
|
|
4577
5035
|
});
|
|
4578
5036
|
};
|
|
4579
5037
|
//#endregion
|
|
@@ -4979,13 +5437,15 @@ var createCore = (options) => {
|
|
|
4979
5437
|
calculateContentDigest: (input) => {
|
|
4980
5438
|
return calculateContentDigest(input, createCoreOperationOptionsSnapshot(snapshot).limits);
|
|
4981
5439
|
},
|
|
4982
|
-
|
|
5440
|
+
inspectProjectPage: (input) => inspectProjectPage(input, createCoreOperationOptionsSnapshot(snapshot)),
|
|
5441
|
+
validateProject: (input) => validateProject(input, createCoreOperationOptionsSnapshot(snapshot)),
|
|
4983
5442
|
matchManifestScope: (input) => matchManifestScope(input, createCoreOperationOptionsSnapshot(snapshot)),
|
|
4984
5443
|
normalizeText: (input) => {
|
|
4985
5444
|
return normalizeTextDocument(input, createCoreOperationOptionsSnapshot(snapshot).limits, "normalize-text");
|
|
4986
5445
|
},
|
|
4987
5446
|
parseDecision: (input) => parseDecisionDocument(input, createCoreOperationOptionsSnapshot(snapshot)),
|
|
4988
|
-
parseManifest: (input) => parseManifestDocument(input, createCoreOperationOptionsSnapshot(snapshot))
|
|
5447
|
+
parseManifest: (input) => parseManifestDocument(input, createCoreOperationOptionsSnapshot(snapshot)),
|
|
5448
|
+
readCanonicalContentPage: (input) => readCanonicalContentPage(input, createCoreOperationOptionsSnapshot(snapshot))
|
|
4989
5449
|
});
|
|
4990
5450
|
};
|
|
4991
5451
|
//#endregion
|