@moldea.ai/core 2.0.2 → 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.
Files changed (63) hide show
  1. package/README.md +43 -86
  2. package/dist/adapter/index.d.ts +97 -14
  3. package/dist/adapter/index.d.ts.map +1 -1
  4. package/dist/adapter-execution/index.d.ts.map +1 -1
  5. package/dist/adapter-repository/index.d.ts +9 -0
  6. package/dist/adapter-repository/index.d.ts.map +1 -0
  7. package/dist/adapter-validation/index.d.ts +2 -3
  8. package/dist/adapter-validation/index.d.ts.map +1 -1
  9. package/dist/adapter.js +93 -0
  10. package/dist/adapter.js.map +1 -0
  11. package/dist/agent-assets/index.d.ts +2 -2
  12. package/dist/agent-assets/index.d.ts.map +1 -1
  13. package/dist/canonical-content-page/index.d.ts +5 -0
  14. package/dist/canonical-content-page/index.d.ts.map +1 -0
  15. package/dist/canonical-discovery/index.d.ts +3 -2
  16. package/dist/canonical-discovery/index.d.ts.map +1 -1
  17. package/dist/chunks/exceptions-DWsZTpqs.js +71 -0
  18. package/dist/chunks/exceptions-DWsZTpqs.js.map +1 -0
  19. package/dist/contracts/index.d.ts +140 -6
  20. package/dist/contracts/index.d.ts.map +1 -1
  21. package/dist/core/index.d.ts.map +1 -1
  22. package/dist/decision/index.d.ts +1 -1
  23. package/dist/decision/index.d.ts.map +1 -1
  24. package/dist/decision-graph/index.d.ts +3 -2
  25. package/dist/decision-graph/index.d.ts.map +1 -1
  26. package/dist/exceptions/index.d.ts +2 -2
  27. package/dist/exceptions/index.d.ts.map +1 -1
  28. package/dist/index.d.ts +2 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +1164 -318
  31. package/dist/index.js.map +1 -1
  32. package/dist/manifest/index.d.ts +2 -2
  33. package/dist/manifest/index.d.ts.map +1 -1
  34. package/dist/mirrors/index.d.ts +3 -2
  35. package/dist/mirrors/index.d.ts.map +1 -1
  36. package/dist/project-assets/index.d.ts +4 -3
  37. package/dist/project-assets/index.d.ts.map +1 -1
  38. package/dist/project-inspection-page/index.d.ts +5 -0
  39. package/dist/project-inspection-page/index.d.ts.map +1 -0
  40. package/dist/project-metadata/index.d.ts +6 -0
  41. package/dist/project-metadata/index.d.ts.map +1 -0
  42. package/dist/{project-inspection → project-validation}/index.d.ts +8 -2
  43. package/dist/project-validation/index.d.ts.map +1 -0
  44. package/dist/repository-inspection-session/index.d.ts +13 -3
  45. package/dist/repository-inspection-session/index.d.ts.map +1 -1
  46. package/dist/repository-reference-validation/index.d.ts +3 -2
  47. package/dist/repository-reference-validation/index.d.ts.map +1 -1
  48. package/dist/repository-text/index.d.ts +3 -2
  49. package/dist/repository-text/index.d.ts.map +1 -1
  50. package/dist/runtime-guidance/index.d.ts +3 -2
  51. package/dist/runtime-guidance/index.d.ts.map +1 -1
  52. package/dist/scope-matching/index.d.ts +5 -0
  53. package/dist/scope-matching/index.d.ts.map +1 -0
  54. package/dist/scope-matching/matching.d.ts +20 -0
  55. package/dist/scope-matching/matching.d.ts.map +1 -0
  56. package/dist/scope-matching/scope.d.ts +14 -0
  57. package/dist/scope-matching/scope.d.ts.map +1 -0
  58. package/dist/scope-matching/types.d.ts +48 -0
  59. package/dist/scope-matching/types.d.ts.map +1 -0
  60. package/dist/scope-matching/validations.d.ts +21 -0
  61. package/dist/scope-matching/validations.d.ts.map +1 -0
  62. package/package.json +2 -2
  63. package/dist/project-inspection/index.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { REPOSITORY_ROOT, RepositoryPathException, RepositorySourceException, isRepositoryPath, parseRepositoryPath } from "@moldea.ai/repository";
2
- import { Exception } from "error-message-utils";
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/exceptions/index.ts
29
- var CONFIGURATION_ERROR_MESSAGES = {
30
- DUPLICATE_ADAPTER_ID: "A runtime adapter ID is registered more than once.",
31
- INVALID_ADAPTER_DEFINITION: "A runtime adapter definition is invalid.",
32
- INVALID_RESOURCE_LIMIT: "A Core resource limit is invalid.",
33
- RESERVED_ADAPTER_ID: "A reserved runtime adapter ID was supplied."
34
- };
35
- var OPERATION_ERROR_MESSAGES = {
36
- ABORTED: "The Core operation was aborted.",
37
- ADAPTER_EXECUTION_FAILED: "A runtime adapter failed during inspection.",
38
- INVALID_ARGUMENT: "The Core operation received an invalid argument.",
39
- RESOURCE_LIMIT_EXCEEDED: "A Core resource limit was exceeded."
40
- };
41
- var OPERATION_ERROR_RETRYABILITY = {
42
- ABORTED: true,
43
- ADAPTER_EXECUTION_FAILED: false,
44
- INVALID_ARGUMENT: false,
45
- RESOURCE_LIMIT_EXCEEDED: false
46
- };
47
- var attachCause = (exception, cause) => {
48
- if (cause === void 0) return;
49
- Object.defineProperty(exception, "cause", {
50
- configurable: true,
51
- enumerable: false,
52
- value: cause,
53
- writable: false
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
- /** Represents invalid immutable Core configuration. */
57
- var CoreConfigurationException = class extends Exception {
58
- code;
59
- operation;
60
- adapterId;
61
- /** Creates a configuration exception with safe adapter metadata. */
62
- constructor(options) {
63
- super(CONFIGURATION_ERROR_MESSAGES[options.code], options.code);
64
- this.code = options.code;
65
- this.name = "CoreConfigurationException";
66
- this.operation = options.operation;
67
- this.adapterId = options.adapterId ?? null;
68
- attachCause(this, options.cause);
69
- }
70
- };
71
- /** Represents an operational failure that prevented Core from completing. */
72
- var CoreOperationException = class extends Exception {
73
- code;
74
- operation;
75
- retryable;
76
- adapterId;
77
- agentId;
78
- limit;
79
- /** Creates an operation exception with derived retry and safe scope metadata. */
80
- constructor(options) {
81
- super(OPERATION_ERROR_MESSAGES[options.code], options.code);
82
- this.code = options.code;
83
- this.name = "CoreOperationException";
84
- this.operation = options.operation;
85
- this.retryable = OPERATION_ERROR_RETRYABILITY[options.code];
86
- this.adapterId = options.adapterId ?? null;
87
- this.agentId = options.agentId ?? null;
88
- this.limit = options.limit ?? null;
89
- attachCause(this, options.cause);
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;
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;
90
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.",
@@ -745,7 +805,7 @@ var invalidAdapter = (adapterId) => {
745
805
  operation: "create-core"
746
806
  });
747
807
  };
748
- var isRecord$3 = (value) => {
808
+ var isRecord$4 = (value) => {
749
809
  return typeof value === "object" && value !== null && !Array.isArray(value);
750
810
  };
751
811
  var isStableId = (value) => {
@@ -760,7 +820,7 @@ var isStableId = (value) => {
760
820
  */
761
821
  var normalizeLimits = (candidate) => {
762
822
  if (candidate === void 0) return DEFAULT_CORE_RESOURCE_LIMITS;
763
- if (!isRecord$3(candidate)) throw new CoreConfigurationException({
823
+ if (!isRecord$4(candidate)) throw new CoreConfigurationException({
764
824
  code: "INVALID_RESOURCE_LIMIT",
765
825
  operation: "create-core"
766
826
  });
@@ -790,7 +850,7 @@ var normalizeLimits = (candidate) => {
790
850
  * - INVALID_ADAPTER_DEFINITION: A runtime adapter definition is invalid.
791
851
  */
792
852
  var normalizeAdapter = (candidate) => {
793
- if (!isRecord$3(candidate)) return invalidAdapter();
853
+ if (!isRecord$4(candidate)) return invalidAdapter();
794
854
  const id = candidate["id"];
795
855
  if (typeof id !== "string" || !isStableId(id) || WINDOWS_RESERVED_ID_PATTERN.test(id)) return invalidAdapter();
796
856
  if (id === "custom") throw new CoreConfigurationException({
@@ -849,7 +909,7 @@ var normalizeAdapters = (candidate) => {
849
909
  * - INVALID_RESOURCE_LIMIT: A Core resource limit is invalid.
850
910
  */
851
911
  var normalizeCoreOptions = (options) => {
852
- if (options !== void 0 && !isRecord$3(options)) return invalidAdapter();
912
+ if (options !== void 0 && !isRecord$4(options)) return invalidAdapter();
853
913
  return freezeRecursively({
854
914
  adapters: normalizeAdapters(options?.["adapters"]),
855
915
  limits: normalizeLimits(options?.["limits"])
@@ -904,12 +964,12 @@ 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
911
971
  });
912
- var isRecord$2 = (value) => {
972
+ var isRecord$3 = (value) => {
913
973
  return typeof value === "object" && value !== null && !Array.isArray(value);
914
974
  };
915
975
  /**
@@ -982,7 +1042,7 @@ var collectNulDiagnostics = (value, path, diagnostics) => {
982
1042
  offset += 1;
983
1043
  }
984
1044
  };
985
- var invalidArgument$1 = (operation) => {
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$2(input)) return invalidArgument$1(operation);
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$1(operation);
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
  /**
@@ -1409,7 +1469,7 @@ var parseDecisionDocument = async (input, options, operation = "parse-decision")
1409
1469
  };
1410
1470
  //#endregion
1411
1471
  //#region src/manifest-validation/index.ts
1412
- var childPointer$1 = (pointer, key) => {
1472
+ var childPointer$2 = (pointer, key) => {
1413
1473
  return `${pointer}/${escapeJsonPointerSegment(key)}`;
1414
1474
  };
1415
1475
  var addInvalidValue = (context, pointer, range, reason, entity = null) => {
@@ -1439,7 +1499,7 @@ var readMapping = (node, pointer, allowedProperties, context, entity = null) =>
1439
1499
  code: "MOLDEA_MANIFEST_PROPERTY_UNKNOWN",
1440
1500
  entity,
1441
1501
  path: context.path,
1442
- pointer: childPointer$1(pointer, key),
1502
+ pointer: childPointer$2(pointer, key),
1443
1503
  range: entry.key.range
1444
1504
  });
1445
1505
  continue;
@@ -1500,7 +1560,7 @@ var readReference = (node, pointer, context, entity = null) => {
1500
1560
  details: { reason: pathEntry === void 0 ? "missing" : "type" },
1501
1561
  entity,
1502
1562
  path: context.path,
1503
- pointer: childPointer$1(pointer, "path"),
1563
+ pointer: childPointer$2(pointer, "path"),
1504
1564
  range: pathEntry?.value.range ?? null
1505
1565
  });
1506
1566
  return null;
@@ -1511,7 +1571,7 @@ var readReference = (node, pointer, context, entity = null) => {
1511
1571
  code: "MOLDEA_PATH_INVALID",
1512
1572
  entity,
1513
1573
  path: context.path,
1514
- pointer: childPointer$1(pointer, "path"),
1574
+ pointer: childPointer$2(pointer, "path"),
1515
1575
  range: pathEntry.value.range
1516
1576
  });
1517
1577
  return null;
@@ -1523,7 +1583,7 @@ var readReference = (node, pointer, context, entity = null) => {
1523
1583
  code: "MOLDEA_SYMBOL_INVALID",
1524
1584
  entity,
1525
1585
  path: context.path,
1526
- pointer: childPointer$1(pointer, "symbol"),
1586
+ pointer: childPointer$2(pointer, "symbol"),
1527
1587
  range: symbolEntry.value.range
1528
1588
  });
1529
1589
  return null;
@@ -1533,7 +1593,7 @@ var readReference = (node, pointer, context, entity = null) => {
1533
1593
  code: "MOLDEA_SYMBOL_FORBIDDEN",
1534
1594
  entity,
1535
1595
  path: context.path,
1536
- pointer: childPointer$1(pointer, "symbol"),
1596
+ pointer: childPointer$2(pointer, "symbol"),
1537
1597
  range: symbolEntry.value.range
1538
1598
  });
1539
1599
  return null;
@@ -1551,7 +1611,7 @@ var readReferenceList = (node, pointer, context, entity = null) => {
1551
1611
  const references = [];
1552
1612
  const seen = /* @__PURE__ */ new Set();
1553
1613
  node.items.forEach((item, index) => {
1554
- const reference = readReference(item, childPointer$1(pointer, String(index)), context, entity);
1614
+ const reference = readReference(item, childPointer$2(pointer, String(index)), context, entity);
1555
1615
  if (reference === null) return;
1556
1616
  const key = `${reference.path}\0${reference.symbol ?? ""}`;
1557
1617
  if (seen.has(key)) {
@@ -1559,7 +1619,7 @@ var readReferenceList = (node, pointer, context, entity = null) => {
1559
1619
  code: "MOLDEA_PATH_DUPLICATE",
1560
1620
  entity,
1561
1621
  path: context.path,
1562
- pointer: childPointer$1(pointer, String(index)),
1622
+ pointer: childPointer$2(pointer, String(index)),
1563
1623
  range: item.range
1564
1624
  });
1565
1625
  return;
@@ -1577,7 +1637,7 @@ var readAffectedBy = (node, pointer, context, entity = null) => {
1577
1637
  const values = [];
1578
1638
  const seen = /* @__PURE__ */ new Set();
1579
1639
  node.items.forEach((item, index) => {
1580
- const itemPointer = childPointer$1(pointer, String(index));
1640
+ const itemPointer = childPointer$2(pointer, String(index));
1581
1641
  if (item.kind !== "scalar" || typeof item.value !== "string") {
1582
1642
  addInvalidValue(context, itemPointer, item.range, "string-required", entity);
1583
1643
  return;
@@ -1620,8 +1680,8 @@ var readRelationship = (node, pointer, context) => {
1620
1680
  range: node.range
1621
1681
  });
1622
1682
  return {
1623
- ...bindingsEntry === void 0 ? {} : { bindings: readReferenceList(bindingsEntry.value, childPointer$1(pointer, "bindings"), context) },
1624
- ...affectedByEntry === void 0 ? {} : { affectedBy: readAffectedBy(affectedByEntry.value, childPointer$1(pointer, "affectedBy"), context) }
1683
+ ...bindingsEntry === void 0 ? {} : { bindings: readReferenceList(bindingsEntry.value, childPointer$2(pointer, "bindings"), context) },
1684
+ ...affectedByEntry === void 0 ? {} : { affectedBy: readAffectedBy(affectedByEntry.value, childPointer$2(pointer, "affectedBy"), context) }
1625
1685
  };
1626
1686
  };
1627
1687
  var readRelationshipRecord = (node, pointer, kind, context) => {
@@ -1634,12 +1694,12 @@ var readRelationshipRecord = (node, pointer, kind, context) => {
1634
1694
  context.diagnostics.add({
1635
1695
  code: kind === "context" ? "MOLDEA_CONTEXT_PATH_INVALID" : "MOLDEA_DECISION_FILENAME_INVALID",
1636
1696
  path: context.path,
1637
- pointer: childPointer$1(pointer, key),
1697
+ pointer: childPointer$2(pointer, key),
1638
1698
  range: entry.key.range
1639
1699
  });
1640
1700
  continue;
1641
1701
  }
1642
- const relationship = readRelationship(entry.value, childPointer$1(pointer, key), context);
1702
+ const relationship = readRelationship(entry.value, childPointer$2(pointer, key), context);
1643
1703
  if (relationship !== null) normalized.push([key, relationship]);
1644
1704
  }
1645
1705
  return createNullPrototypeRecord(normalized);
@@ -1652,7 +1712,7 @@ var readPathList = (node, pointer, kind, context, entity) => {
1652
1712
  const paths = [];
1653
1713
  const seen = /* @__PURE__ */ new Set();
1654
1714
  node.items.forEach((item, index) => {
1655
- const itemPointer = childPointer$1(pointer, String(index));
1715
+ const itemPointer = childPointer$2(pointer, String(index));
1656
1716
  if (item.kind !== "scalar" || typeof item.value !== "string") {
1657
1717
  addInvalidValue(context, itemPointer, item.range, "string-required", entity);
1658
1718
  return;
@@ -1705,7 +1765,7 @@ var readRuntime = (node, pointer, context, agentId) => {
1705
1765
  code: "MOLDEA_RUNTIME_ID_INVALID",
1706
1766
  entity,
1707
1767
  path: context.path,
1708
- pointer: childPointer$1(pointer, "id"),
1768
+ pointer: childPointer$2(pointer, "id"),
1709
1769
  range: idEntry?.value.range ?? null
1710
1770
  });
1711
1771
  return null;
@@ -1715,14 +1775,14 @@ var readRuntime = (node, pointer, context, agentId) => {
1715
1775
  code: "MOLDEA_RUNTIME_ID_INVALID",
1716
1776
  entity,
1717
1777
  path: context.path,
1718
- pointer: childPointer$1(pointer, "id"),
1778
+ pointer: childPointer$2(pointer, "id"),
1719
1779
  range: idEntry.value.range
1720
1780
  });
1721
1781
  else context.runtimeLocations.push({
1722
1782
  adapterId: id,
1723
1783
  agentId,
1724
1784
  path: context.path,
1725
- pointer: childPointer$1(pointer, "id"),
1785
+ pointer: childPointer$2(pointer, "id"),
1726
1786
  range: idEntry.value.range
1727
1787
  });
1728
1788
  const guidanceEntry = entries.get("guidance");
@@ -1736,7 +1796,7 @@ var readRuntime = (node, pointer, context, agentId) => {
1736
1796
  details: { reason: "runtime-guidance" },
1737
1797
  entity,
1738
1798
  path: context.path,
1739
- pointer: childPointer$1(pointer, "guidance"),
1799
+ pointer: childPointer$2(pointer, "guidance"),
1740
1800
  range: guidanceEntry.value.range
1741
1801
  });
1742
1802
  } else context.diagnostics.add({
@@ -1744,7 +1804,7 @@ var readRuntime = (node, pointer, context, agentId) => {
1744
1804
  details: { reason: "runtime-guidance" },
1745
1805
  entity,
1746
1806
  path: context.path,
1747
- pointer: childPointer$1(pointer, "guidance"),
1807
+ pointer: childPointer$2(pointer, "guidance"),
1748
1808
  range: guidanceEntry.value.range
1749
1809
  });
1750
1810
  }
@@ -1766,13 +1826,13 @@ var readVariables = (node, pointer, context, agentId) => {
1766
1826
  code: "MOLDEA_VARIABLE_ID_INVALID",
1767
1827
  entity,
1768
1828
  path: context.path,
1769
- pointer: childPointer$1(pointer, variableId),
1829
+ pointer: childPointer$2(pointer, variableId),
1770
1830
  range: entry.key.range
1771
1831
  });
1772
- const variablePointer = childPointer$1(pointer, variableId);
1832
+ const variablePointer = childPointer$2(pointer, variableId);
1773
1833
  const variableEntries = readMapping(entry.value, variablePointer, /* @__PURE__ */ new Set(["description"]), context, entity);
1774
1834
  if (variableEntries === null) continue;
1775
- const description = readString(variableEntries.get("description"), childPointer$1(variablePointer, "description"), context, {
1835
+ const description = readString(variableEntries.get("description"), childPointer$2(variablePointer, "description"), context, {
1776
1836
  entity,
1777
1837
  required: true
1778
1838
  });
@@ -1792,7 +1852,7 @@ var readBindings = (node, pointer, context, agentId, declaredVariables) => {
1792
1852
  if (entries === null) return null;
1793
1853
  const referenceProperty = (key) => {
1794
1854
  const entry = entries.get(key);
1795
- return entry === void 0 ? null : readReference(entry.value, childPointer$1(pointer, key), context, entity);
1855
+ return entry === void 0 ? null : readReference(entry.value, childPointer$2(pointer, key), context, entity);
1796
1856
  };
1797
1857
  const inputSchema = referenceProperty("inputSchema");
1798
1858
  const instructionLoader = referenceProperty("instructionLoader");
@@ -1801,7 +1861,7 @@ var readBindings = (node, pointer, context, agentId, declaredVariables) => {
1801
1861
  const providersEntry = entries.get("variableProviders");
1802
1862
  let variableProviders = null;
1803
1863
  if (providersEntry !== void 0) {
1804
- const providers = readMapping(providersEntry.value, childPointer$1(pointer, "variableProviders"), null, context, entity);
1864
+ const providers = readMapping(providersEntry.value, childPointer$2(pointer, "variableProviders"), null, context, entity);
1805
1865
  if (providers !== null) {
1806
1866
  const normalized = [];
1807
1867
  for (const [variableId, providerEntry] of [...providers].sort(([left], [right]) => compareExactStrings(left, right))) {
@@ -1809,7 +1869,7 @@ var readBindings = (node, pointer, context, agentId, declaredVariables) => {
1809
1869
  agentId,
1810
1870
  variableId
1811
1871
  };
1812
- const providerPointer = childPointer$1(childPointer$1(pointer, "variableProviders"), variableId);
1872
+ const providerPointer = childPointer$2(childPointer$2(pointer, "variableProviders"), variableId);
1813
1873
  if (!isVariableId(variableId)) context.diagnostics.add({
1814
1874
  code: "MOLDEA_VARIABLE_ID_INVALID",
1815
1875
  entity: variableEntity,
@@ -1860,7 +1920,7 @@ var readCapability$1 = (node, pointer, context, agentId, capabilityId, kind) =>
1860
1920
  "registration"
1861
1921
  ]), context, entity);
1862
1922
  if (entries === null) return null;
1863
- const name = readString(entries.get("name"), childPointer$1(pointer, "name"), context, {
1923
+ const name = readString(entries.get("name"), childPointer$2(pointer, "name"), context, {
1864
1924
  entity,
1865
1925
  required: true,
1866
1926
  singleLine: true
@@ -1871,13 +1931,13 @@ var readCapability$1 = (node, pointer, context, agentId, capabilityId, kind) =>
1871
1931
  code: "MOLDEA_CAPABILITY_DESCRIPTION_MISSING",
1872
1932
  entity,
1873
1933
  path: context.path,
1874
- pointer: childPointer$1(pointer, "description")
1934
+ pointer: childPointer$2(pointer, "description")
1875
1935
  });
1876
1936
  else if (descriptionEntry.value.kind !== "scalar" || typeof descriptionEntry.value.value !== "string" || !isCapabilityDescription(descriptionEntry.value.value)) context.diagnostics.add({
1877
1937
  code: "MOLDEA_CAPABILITY_DESCRIPTION_INVALID",
1878
1938
  entity,
1879
1939
  path: context.path,
1880
- pointer: childPointer$1(pointer, "description"),
1940
+ pointer: childPointer$2(pointer, "description"),
1881
1941
  range: descriptionEntry.value.range
1882
1942
  });
1883
1943
  else description = descriptionEntry.value.value;
@@ -1887,18 +1947,18 @@ var readCapability$1 = (node, pointer, context, agentId, capabilityId, kind) =>
1887
1947
  code: kind === "tool" ? "MOLDEA_TOOL_IMPLEMENTATION_MISSING" : "MOLDEA_SKILL_IMPLEMENTATION_MISSING",
1888
1948
  entity,
1889
1949
  path: context.path,
1890
- pointer: childPointer$1(pointer, "implementation")
1950
+ pointer: childPointer$2(pointer, "implementation")
1891
1951
  });
1892
- else implementation = readReference(implementationEntry.value, childPointer$1(pointer, "implementation"), context, entity);
1952
+ else implementation = readReference(implementationEntry.value, childPointer$2(pointer, "implementation"), context, entity);
1893
1953
  const optionalReference = (key) => {
1894
1954
  const entry = entries.get(key);
1895
- return entry === void 0 ? null : readReference(entry.value, childPointer$1(pointer, key), context, entity);
1955
+ return entry === void 0 ? null : readReference(entry.value, childPointer$2(pointer, key), context, entity);
1896
1956
  };
1897
1957
  const registration = optionalReference("registration");
1898
1958
  const inputSchema = kind === "tool" ? optionalReference("inputSchema") : null;
1899
1959
  const outputSchema = kind === "tool" ? optionalReference("outputSchema") : null;
1900
1960
  const affectedByEntry = entries.get("affectedBy");
1901
- const affectedBy = affectedByEntry === void 0 ? null : readAffectedBy(affectedByEntry.value, childPointer$1(pointer, "affectedBy"), context, entity);
1961
+ const affectedBy = affectedByEntry === void 0 ? null : readAffectedBy(affectedByEntry.value, childPointer$2(pointer, "affectedBy"), context, entity);
1902
1962
  if (name === null || description === null || implementation === null) return null;
1903
1963
  return {
1904
1964
  name,
@@ -1920,7 +1980,7 @@ var readCapabilities = (node, pointer, context, agentId, kind) => {
1920
1980
  capabilityId,
1921
1981
  capabilityKind: kind
1922
1982
  };
1923
- const capabilityPointer = childPointer$1(pointer, capabilityId);
1983
+ const capabilityPointer = childPointer$2(pointer, capabilityId);
1924
1984
  validateStableId(capabilityId, entry.key.range, capabilityPointer, context, entity);
1925
1985
  const capability = readCapability$1(entry.value, capabilityPointer, context, agentId, capabilityId, kind);
1926
1986
  if (capability !== null) normalized.push([capabilityId, capability]);
@@ -1933,7 +1993,7 @@ var readUnresolved = (node, pointer, context, agentId) => {
1933
1993
  const normalized = [];
1934
1994
  for (const [requirementId, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
1935
1995
  const entity = agentId === void 0 ? null : { agentId };
1936
- const requirementPointer = childPointer$1(pointer, requirementId);
1996
+ const requirementPointer = childPointer$2(pointer, requirementId);
1937
1997
  validateStableId(requirementId, entry.key.range, requirementPointer, context, entity);
1938
1998
  const requirementEntries = readMapping(entry.value, requirementPointer, /* @__PURE__ */ new Set([
1939
1999
  "category",
@@ -1944,7 +2004,7 @@ var readUnresolved = (node, pointer, context, agentId) => {
1944
2004
  "resolution"
1945
2005
  ]), context, entity);
1946
2006
  if (requirementEntries === null) continue;
1947
- const category = readString(requirementEntries.get("category"), childPointer$1(requirementPointer, "category"), context, {
2007
+ const category = readString(requirementEntries.get("category"), childPointer$2(requirementPointer, "category"), context, {
1948
2008
  ...entity === null ? {} : { entity },
1949
2009
  required: true
1950
2010
  });
@@ -1952,24 +2012,24 @@ var readUnresolved = (node, pointer, context, agentId) => {
1952
2012
  code: "MOLDEA_ID_INVALID",
1953
2013
  entity,
1954
2014
  path: context.path,
1955
- pointer: childPointer$1(requirementPointer, "category"),
2015
+ pointer: childPointer$2(requirementPointer, "category"),
1956
2016
  range: requirementEntries.get("category")?.value.range ?? null
1957
2017
  });
1958
2018
  const effectEntry = requirementEntries.get("effect");
1959
2019
  let effect = null;
1960
2020
  if (effectEntry?.value.kind === "scalar" && (effectEntry.value.value === "blocking" || effectEntry.value.value === "warning" || effectEntry.value.value === "informational")) effect = effectEntry.value.value;
1961
- else addInvalidValue(context, childPointer$1(requirementPointer, "effect"), effectEntry?.value.range ?? null, effectEntry === void 0 ? "required" : "enum", entity);
1962
- const description = readString(requirementEntries.get("description"), childPointer$1(requirementPointer, "description"), context, {
2021
+ else addInvalidValue(context, childPointer$2(requirementPointer, "effect"), effectEntry?.value.range ?? null, effectEntry === void 0 ? "required" : "enum", entity);
2022
+ const description = readString(requirementEntries.get("description"), childPointer$2(requirementPointer, "description"), context, {
1963
2023
  ...entity === null ? {} : { entity },
1964
2024
  required: true
1965
2025
  });
1966
- const resolution = readString(requirementEntries.get("resolution"), childPointer$1(requirementPointer, "resolution"), context, {
2026
+ const resolution = readString(requirementEntries.get("resolution"), childPointer$2(requirementPointer, "resolution"), context, {
1967
2027
  ...entity === null ? {} : { entity },
1968
2028
  required: true
1969
2029
  });
1970
2030
  const relatedEntry = requirementEntries.get("related");
1971
- const related = relatedEntry === void 0 ? null : readReferenceList(relatedEntry.value, childPointer$1(requirementPointer, "related"), context, entity);
1972
- const reference = readString(requirementEntries.get("reference"), childPointer$1(requirementPointer, "reference"), context, {
2031
+ const related = relatedEntry === void 0 ? null : readReferenceList(relatedEntry.value, childPointer$2(requirementPointer, "related"), context, entity);
2032
+ const reference = readString(requirementEntries.get("reference"), childPointer$2(requirementPointer, "reference"), context, {
1973
2033
  ...entity === null ? {} : { entity },
1974
2034
  singleLine: true
1975
2035
  });
@@ -2014,7 +2074,7 @@ var validateAgentOwnedIdUniqueness = (node, pointer, context, agentId) => {
2014
2074
  code: "MOLDEA_ID_DUPLICATE",
2015
2075
  entity: { agentId },
2016
2076
  path: context.path,
2017
- pointer: childPointer$1(childPointer$1(pointer, property), entry.key.value),
2077
+ pointer: childPointer$2(childPointer$2(pointer, property), entry.key.value),
2018
2078
  range: entry.key.range
2019
2079
  });
2020
2080
  seen.add(entry.key.value);
@@ -2039,27 +2099,27 @@ var readAgent = (node, pointer, context, agentId) => {
2039
2099
  validateAgentOwnedIdUniqueness(node, pointer, context, agentId);
2040
2100
  const runtimeEntry = entries.get("runtime");
2041
2101
  let runtime = null;
2042
- if (runtimeEntry === void 0) addInvalidValue(context, childPointer$1(pointer, "runtime"), null, "required", entity);
2043
- else runtime = readRuntime(runtimeEntry.value, childPointer$1(pointer, "runtime"), context, agentId);
2102
+ if (runtimeEntry === void 0) addInvalidValue(context, childPointer$2(pointer, "runtime"), null, "required", entity);
2103
+ else runtime = readRuntime(runtimeEntry.value, childPointer$2(pointer, "runtime"), context, agentId);
2044
2104
  const variablesEntry = entries.get("variables");
2045
- const variables = variablesEntry === void 0 ? null : readVariables(variablesEntry.value, childPointer$1(pointer, "variables"), context, agentId);
2105
+ const variables = variablesEntry === void 0 ? null : readVariables(variablesEntry.value, childPointer$2(pointer, "variables"), context, agentId);
2046
2106
  const declaredVariables = new Set(Object.keys(variables ?? {}));
2047
2107
  const bindingsEntry = entries.get("bindings");
2048
- const bindings = bindingsEntry === void 0 ? null : readBindings(bindingsEntry.value, childPointer$1(pointer, "bindings"), context, agentId, declaredVariables);
2108
+ const bindings = bindingsEntry === void 0 ? null : readBindings(bindingsEntry.value, childPointer$2(pointer, "bindings"), context, agentId, declaredVariables);
2049
2109
  const contextEntry = entries.get("context");
2050
- const contextPaths = contextEntry === void 0 ? null : readPathList(contextEntry.value, childPointer$1(pointer, "context"), "context", context, entity);
2110
+ const contextPaths = contextEntry === void 0 ? null : readPathList(contextEntry.value, childPointer$2(pointer, "context"), "context", context, entity);
2051
2111
  const decisionsEntry = entries.get("decisions");
2052
- const decisions = decisionsEntry === void 0 ? null : readPathList(decisionsEntry.value, childPointer$1(pointer, "decisions"), "decision", context, entity);
2112
+ const decisions = decisionsEntry === void 0 ? null : readPathList(decisionsEntry.value, childPointer$2(pointer, "decisions"), "decision", context, entity);
2053
2113
  const toolsEntry = entries.get("tools");
2054
- const tools = toolsEntry === void 0 ? null : readCapabilities(toolsEntry.value, childPointer$1(pointer, "tools"), context, agentId, "tool");
2114
+ const tools = toolsEntry === void 0 ? null : readCapabilities(toolsEntry.value, childPointer$2(pointer, "tools"), context, agentId, "tool");
2055
2115
  const skillsEntry = entries.get("skills");
2056
- const skills = skillsEntry === void 0 ? null : readCapabilities(skillsEntry.value, childPointer$1(pointer, "skills"), context, agentId, "skill");
2116
+ const skills = skillsEntry === void 0 ? null : readCapabilities(skillsEntry.value, childPointer$2(pointer, "skills"), context, agentId, "skill");
2057
2117
  const affectedByEntry = entries.get("affectedBy");
2058
- const affectedBy = affectedByEntry === void 0 ? null : readAffectedBy(affectedByEntry.value, childPointer$1(pointer, "affectedBy"), context, entity);
2118
+ const affectedBy = affectedByEntry === void 0 ? null : readAffectedBy(affectedByEntry.value, childPointer$2(pointer, "affectedBy"), context, entity);
2059
2119
  const mirrorsEntry = entries.get("mirrors");
2060
- const mirrors = mirrorsEntry === void 0 ? null : readPathList(mirrorsEntry.value, childPointer$1(pointer, "mirrors"), "mirror", context, entity);
2120
+ const mirrors = mirrorsEntry === void 0 ? null : readPathList(mirrorsEntry.value, childPointer$2(pointer, "mirrors"), "mirror", context, entity);
2061
2121
  const unresolvedEntry = entries.get("unresolved");
2062
- const unresolved = unresolvedEntry === void 0 ? null : readUnresolved(unresolvedEntry.value, childPointer$1(pointer, "unresolved"), context, agentId);
2122
+ const unresolved = unresolvedEntry === void 0 ? null : readUnresolved(unresolvedEntry.value, childPointer$2(pointer, "unresolved"), context, agentId);
2063
2123
  if (runtime === null) return null;
2064
2124
  return {
2065
2125
  runtime,
@@ -2079,7 +2139,7 @@ var readAgents = (node, pointer, context) => {
2079
2139
  if (entries === null) return null;
2080
2140
  const normalized = [];
2081
2141
  for (const [agentId, entry] of [...entries].sort(([left], [right]) => compareExactStrings(left, right))) {
2082
- const agentPointer = childPointer$1(pointer, agentId);
2142
+ const agentPointer = childPointer$2(pointer, agentId);
2083
2143
  validateStableId(agentId, entry.key.range, agentPointer, context, { agentId });
2084
2144
  const agent = readAgent(entry.value, agentPointer, context, agentId);
2085
2145
  if (agent !== null) normalized.push([agentId, agent]);
@@ -2230,8 +2290,8 @@ var inspectManifestDocument = async (input, options, operation = "parse-manifest
2230
2290
  * - INVALID_ARGUMENT: The Core operation received an invalid argument.
2231
2291
  * - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
2232
2292
  */
2233
- var parseManifestDocument = async (input, options) => {
2234
- const inspection = await inspectManifestDocument(input, options);
2293
+ var parseManifestDocument = async (input, options, operation = "parse-manifest") => {
2294
+ const inspection = await inspectManifestDocument(input, options, operation);
2235
2295
  return freezeRecursively({
2236
2296
  asset: inspection.asset,
2237
2297
  diagnostics: inspection.diagnostics,
@@ -2240,6 +2300,57 @@ var parseManifestDocument = async (input, options) => {
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) => {
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, "inspect-project");
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;
@@ -2333,7 +2444,7 @@ var DIAGNOSTIC_KEYS = /* @__PURE__ */ new Set([
2333
2444
  ]);
2334
2445
  var ADAPTER_RESULT_KEYS = /* @__PURE__ */ new Set(["evidence", "diagnostics"]);
2335
2446
  var ADAPTER_CODE_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
2336
- var isRecord$1 = (candidate) => {
2447
+ var isRecord$2 = (candidate) => {
2337
2448
  return typeof candidate === "object" && candidate !== null && !Array.isArray(candidate);
2338
2449
  };
2339
2450
  var invalidAdapterResult = (adapterId) => {
@@ -2365,7 +2476,7 @@ var isSafeString = (candidate) => {
2365
2476
  return typeof candidate === "string" && isUnicodeScalarText(candidate) && !candidate.includes("\0");
2366
2477
  };
2367
2478
  var normalizeDetails = (candidate, adapterId) => {
2368
- if (!isRecord$1(candidate)) return invalidAdapterResult(adapterId);
2479
+ if (!isRecord$2(candidate)) return invalidAdapterResult(adapterId);
2369
2480
  const entries = [];
2370
2481
  for (const key of Reflect.ownKeys(candidate)) {
2371
2482
  if (typeof key !== "string" || !isUnicodeScalarText(key) || key.includes("\0")) return invalidAdapterResult(adapterId);
@@ -2378,7 +2489,7 @@ var normalizeDetails = (candidate, adapterId) => {
2378
2489
  return normalizeDiagnosticDetails(createNullPrototypeRecord(entries));
2379
2490
  };
2380
2491
  var normalizePosition = (candidate, adapterId) => {
2381
- if (!isRecord$1(candidate) || !hasOnlyKeys(candidate, POSITION_KEYS) || !Number.isSafeInteger(candidate["line"]) || !Number.isSafeInteger(candidate["column"]) || !Number.isSafeInteger(candidate["offset"]) || candidate["line"] < 1 || candidate["column"] < 1 || candidate["offset"] < 0) return invalidAdapterResult(adapterId);
2492
+ if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, POSITION_KEYS) || !Number.isSafeInteger(candidate["line"]) || !Number.isSafeInteger(candidate["column"]) || !Number.isSafeInteger(candidate["offset"]) || candidate["line"] < 1 || candidate["column"] < 1 || candidate["offset"] < 0) return invalidAdapterResult(adapterId);
2382
2493
  return freezeRecursively({
2383
2494
  column: candidate["column"],
2384
2495
  line: candidate["line"],
@@ -2387,7 +2498,7 @@ var normalizePosition = (candidate, adapterId) => {
2387
2498
  };
2388
2499
  var normalizeRange = (candidate, adapterId) => {
2389
2500
  if (candidate === null) return null;
2390
- if (!isRecord$1(candidate) || !hasOnlyKeys(candidate, RANGE_KEYS)) return invalidAdapterResult(adapterId);
2501
+ if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, RANGE_KEYS)) return invalidAdapterResult(adapterId);
2391
2502
  const start = normalizePosition(candidate["start"], adapterId);
2392
2503
  const end = normalizePosition(candidate["end"], adapterId);
2393
2504
  if (!(end.line > start.line || end.line === start.line && end.column >= start.column) || end.offset < start.offset) return invalidAdapterResult(adapterId);
@@ -2405,7 +2516,7 @@ var readCapability = (agent, capabilityKind, capabilityId) => {
2405
2516
  };
2406
2517
  var normalizeEntity = (candidate, context) => {
2407
2518
  if (candidate === null) return null;
2408
- if (!isRecord$1(candidate) || !hasOnlyKeys(candidate, DIAGNOSTIC_ENTITY_KEYS)) return invalidAdapterResult(context.adapterId);
2519
+ if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, DIAGNOSTIC_ENTITY_KEYS)) return invalidAdapterResult(context.adapterId);
2409
2520
  const entity = {};
2410
2521
  for (const key of DIAGNOSTIC_ENTITY_KEYS) {
2411
2522
  const candidateValue = candidate[key];
@@ -2427,7 +2538,7 @@ var normalizeEntity = (candidate, context) => {
2427
2538
  return normalizeDiagnosticEntity(entity);
2428
2539
  };
2429
2540
  var normalizeReference = (candidate, adapterId) => {
2430
- if (!isRecord$1(candidate) || !hasOnlyKeys(candidate, REFERENCE_KEYS)) return invalidAdapterResult(adapterId);
2541
+ if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, REFERENCE_KEYS)) return invalidAdapterResult(adapterId);
2431
2542
  const pathCandidate = candidate["path"];
2432
2543
  const symbolCandidate = candidate["symbol"];
2433
2544
  if (typeof pathCandidate !== "string" || !isRepositoryPath(pathCandidate)) return invalidAdapterResult(adapterId);
@@ -2450,7 +2561,7 @@ var normalizeReferences = (candidate, adapterId) => {
2450
2561
  return freezeRecursively(sortRepositoryReferences(references));
2451
2562
  };
2452
2563
  var normalizeEvidence = (candidate, context) => {
2453
- if (!isRecord$1(candidate) || !hasOnlyKeys(candidate, EVIDENCE_KEYS)) return invalidAdapterResult(context.adapterId);
2564
+ if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, EVIDENCE_KEYS)) return invalidAdapterResult(context.adapterId);
2454
2565
  const source = candidate["source"];
2455
2566
  const kind = candidate["kind"];
2456
2567
  const agentId = candidate["agentId"];
@@ -2484,7 +2595,7 @@ var validateEvidenceReferences = async (evidence, context) => {
2484
2595
  }
2485
2596
  };
2486
2597
  var normalizeDiagnostic = (candidate, context) => {
2487
- if (!isRecord$1(candidate) || !hasOnlyKeys(candidate, DIAGNOSTIC_KEYS)) return invalidAdapterResult(context.adapterId);
2598
+ if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, DIAGNOSTIC_KEYS)) return invalidAdapterResult(context.adapterId);
2488
2599
  const source = candidate["source"];
2489
2600
  const code = candidate["code"];
2490
2601
  const message = candidate["message"];
@@ -2556,7 +2667,7 @@ var validateRuntimeAdapterResult = async (candidate, context, outputCounts) => {
2556
2667
  let evidence;
2557
2668
  let validationState;
2558
2669
  try {
2559
- if (!isRecord$1(candidate) || !hasOnlyKeys(candidate, ADAPTER_RESULT_KEYS)) return invalidAdapterResult(context.adapterId);
2670
+ if (!isRecord$2(candidate) || !hasOnlyKeys(candidate, ADAPTER_RESULT_KEYS)) return invalidAdapterResult(context.adapterId);
2560
2671
  const evidenceValue = candidate["evidence"];
2561
2672
  const diagnosticsValue = candidate["diagnostics"];
2562
2673
  if (!Array.isArray(evidenceValue) || !Array.isArray(diagnosticsValue)) return invalidAdapterResult(context.adapterId);
@@ -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 === "inspect-project" && (error.code === "ABORTED" || error.code === "RESOURCE_LIMIT_EXCEEDED");
2593
- };
2594
- var invokeAdapter = async (adapter, project, session, options, outputCounts, signal) => {
2595
- const agents = freezeRecursively(project.agents.filter(({ declaration }) => declaration.runtime.id === adapter.id));
2596
- if (agents.length === 0) return freezeRecursively({
2597
- diagnostics: [],
2598
- evidence: []
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
- agents,
2602
- project,
2603
- repository: session.reader,
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: "inspect-project"
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.reader,
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 result = await invokeAdapter(adapter, project, session, options, outputCounts, signal);
2659
- evidence.push(...result.evidence);
2660
- diagnostics.push(...result.diagnostics);
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: "inspect-project"
2869
+ operation: "validate-project"
2702
2870
  });
2703
2871
  };
2704
2872
  var createSourceOptions = (sessionSignal, operationSignal) => {
2705
- const signal = sessionSignal ?? operationSignal;
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 frozen session whose reader owns inspection-local budgets and byte caching.
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: "inspect-project"
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 === null) return;
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 listEntries = (options) => {
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
- const sourceOptions = createSourceOptions(signal, options?.signal);
2754
- const sourceListOptions = sourceOptions === void 0 ? { prefix } : {
2755
- prefix,
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 entry = copyReaderEntry$1(candidate, "list-entries", prefix);
2761
- if (!isStrictDescendant(entry.path, prefix) || yieldedPaths.has(entry.path)) return invalidSourceData$3("list-entries", entry.path);
2762
- yieldedPaths.add(entry.path);
2763
- registerPath(entry.path);
2764
- yield entry;
2765
- }
2766
- throwIfSignalAborted(options?.signal);
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
- if (content.byteLength > limits[fileLimit]) return throwResourceLimitExceeded(fileLimit);
2775
- if (totalBytesRead + content.byteLength > limits.maxTotalBytesRead) return throwResourceLimitExceeded("maxTotalBytesRead");
2776
- totalBytesRead += content.byteLength;
2777
- return new Uint8Array(content);
2778
- };
2779
- const removeFailedRead = async (path, readPromise) => {
2780
- try {
2781
- return await readPromise;
2782
- } catch (error) {
2783
- readCache.delete(path);
2784
- throw error;
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 waitForRead = (readPromise, operationSignal) => {
2788
- throwIfSignalAborted(operationSignal);
2789
- if (operationSignal === void 0 || operationSignal === signal) return readPromise;
2790
- let handleAbort;
2791
- const cancellationPromise = new Promise((resolve, reject) => {
2792
- handleAbort = () => {
2793
- const abortedSignal = signal?.aborted ? signal : operationSignal;
2794
- reject(createAbortedException(abortedSignal));
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
- operationSignal.addEventListener("abort", handleAbort, { once: true });
2797
- if (operationSignal.aborted) handleAbort();
2798
- });
2799
- return Promise.race([readPromise, cancellationPromise]).finally(() => {
2800
- operationSignal.removeEventListener("abort", handleAbort);
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 readFile = async (path, options) => {
3018
+ const readCompleteFile = async (path, options) => {
2804
3019
  const parsedPath = parseRepositoryPath(path);
2805
3020
  throwIfSignalAborted(options?.signal);
2806
3021
  registerPath(parsedPath);
2807
- let readPromise = readCache.get(parsedPath);
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 new Uint8Array(content);
3024
+ return content.slice();
2815
3025
  };
2816
- const reader = Object.freeze({
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
+ });
3087
+ };
3088
+ const adapterRepository = Object.freeze({
2817
3089
  getEntry,
2818
- listEntries,
2819
- readFile
3090
+ limits: adapterLimits,
3091
+ listEntriesPage: listAdapterEntriesPage,
3092
+ readFilePage: readAdapterFilePage,
3093
+ snapshot: repository.snapshot
2820
3094
  });
2821
3095
  return Object.freeze({
2822
- reader,
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, "inspect-project");
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, "inspect-project");
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.readFile(path, signal === void 0 ? void 0 : { signal });
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, "inspect-project");
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, "inspect-project");
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, "inspect-project");
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, "inspect-project");
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.listEntries(listOptions)) {
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, "inspect-project");
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, "inspect-project");
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.readFile(path, readOptions);
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, "inspect-project");
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, "inspect-project");
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, "inspect-project");
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, "inspect-project");
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, "inspect-project");
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);
@@ -4118,7 +4404,7 @@ var createProjectIndex = (input) => {
4118
4404
  };
4119
4405
  //#endregion
4120
4406
  //#region src/repository-reference-validation/index.ts
4121
- var childPointer = (pointer, segment) => {
4407
+ var childPointer$1 = (pointer, segment) => {
4122
4408
  return `${pointer}/${escapeJsonPointerSegment(segment)}`;
4123
4409
  };
4124
4410
  var compareNullableStrings = (left, right) => {
@@ -4134,7 +4420,7 @@ var addReferenceCandidates = (candidates, references, pointer, entity) => {
4134
4420
  entity,
4135
4421
  kind: "reference",
4136
4422
  path: reference.path,
4137
- pointer: childPointer(pointer, String(index))
4423
+ pointer: childPointer$1(pointer, String(index))
4138
4424
  });
4139
4425
  };
4140
4426
  /** Adds sorted exact impact paths while retaining skipped glob indexes. */
@@ -4145,26 +4431,26 @@ var addImpactCandidates = (candidates, affectedBy, pointer, entity) => {
4145
4431
  entity,
4146
4432
  kind: "impact",
4147
4433
  path: parseRepositoryPath(pattern),
4148
- pointer: childPointer(pointer, String(index))
4434
+ pointer: childPointer$1(pointer, String(index))
4149
4435
  });
4150
4436
  }
4151
4437
  };
4152
4438
  /** Adds repository-backed declarations owned by one context or decision relationship. */
4153
4439
  var addRelationshipCandidates = (candidates, relationship, pointer, entity) => {
4154
- addReferenceCandidates(candidates, relationship.bindings, childPointer(pointer, "bindings"), entity);
4155
- addImpactCandidates(candidates, relationship.affectedBy, childPointer(pointer, "affectedBy"), entity);
4440
+ addReferenceCandidates(candidates, relationship.bindings, childPointer$1(pointer, "bindings"), entity);
4441
+ addImpactCandidates(candidates, relationship.affectedBy, childPointer$1(pointer, "affectedBy"), entity);
4156
4442
  };
4157
4443
  /** Adds related repository references from sorted unresolved requirements. */
4158
4444
  var addUnresolvedCandidates = (candidates, requirements, pointer, entity) => {
4159
4445
  for (const requirementId of Object.keys(requirements ?? {}).sort(compareExactStrings)) {
4160
4446
  const requirement = requirements?.[requirementId];
4161
4447
  if (requirement === void 0) continue;
4162
- addReferenceCandidates(candidates, requirement.related, childPointer(childPointer(pointer, requirementId), "related"), entity);
4448
+ addReferenceCandidates(candidates, requirement.related, childPointer$1(childPointer$1(pointer, requirementId), "related"), entity);
4163
4449
  }
4164
4450
  };
4165
4451
  /** Adds one capability's implementation, optional bindings, and exact impact paths. */
4166
4452
  var addCapabilityCandidates = (candidates, capability, capabilityKind, capabilityId, agentId, collectionPointer, additionalReferences = []) => {
4167
- const capabilityPointer = childPointer(collectionPointer, capabilityId);
4453
+ const capabilityPointer = childPointer$1(collectionPointer, capabilityId);
4168
4454
  const capabilityEntity = {
4169
4455
  agentId,
4170
4456
  capabilityId,
@@ -4174,21 +4460,21 @@ var addCapabilityCandidates = (candidates, capability, capabilityKind, capabilit
4174
4460
  entity: capabilityEntity,
4175
4461
  kind: `${capabilityKind}-implementation`,
4176
4462
  path: capability.implementation.path,
4177
- pointer: childPointer(capabilityPointer, "implementation")
4463
+ pointer: childPointer$1(capabilityPointer, "implementation")
4178
4464
  });
4179
4465
  for (const [property, reference] of [["registration", capability.registration], ...additionalReferences]) if (reference !== void 0) candidates.push({
4180
4466
  entity: capabilityEntity,
4181
4467
  kind: "reference",
4182
4468
  path: reference.path,
4183
- pointer: childPointer(capabilityPointer, property)
4469
+ pointer: childPointer$1(capabilityPointer, property)
4184
4470
  });
4185
- addImpactCandidates(candidates, capability.affectedBy, childPointer(capabilityPointer, "affectedBy"), capabilityEntity);
4471
+ addImpactCandidates(candidates, capability.affectedBy, childPointer$1(capabilityPointer, "affectedBy"), capabilityEntity);
4186
4472
  };
4187
4473
  /** Adds all repository-backed declarations owned by one normalized agent. */
4188
4474
  var addAgentCandidates = (candidates, agentId, agent) => {
4189
4475
  const pointer = `/agents/${escapeJsonPointerSegment(agentId)}`;
4190
4476
  const entity = { agentId };
4191
- const bindingsPointer = childPointer(pointer, "bindings");
4477
+ const bindingsPointer = childPointer$1(pointer, "bindings");
4192
4478
  const bindings = agent.bindings;
4193
4479
  for (const property of [
4194
4480
  "runtimeAgent",
@@ -4201,7 +4487,7 @@ var addAgentCandidates = (candidates, agentId, agent) => {
4201
4487
  entity,
4202
4488
  kind: "reference",
4203
4489
  path: reference.path,
4204
- pointer: childPointer(bindingsPointer, property)
4490
+ pointer: childPointer$1(bindingsPointer, property)
4205
4491
  });
4206
4492
  }
4207
4493
  for (const variableId of Object.keys(bindings?.variableProviders ?? {}).sort(compareExactStrings)) {
@@ -4213,21 +4499,21 @@ var addAgentCandidates = (candidates, agentId, agent) => {
4213
4499
  },
4214
4500
  kind: "reference",
4215
4501
  path: reference.path,
4216
- pointer: childPointer(childPointer(bindingsPointer, "variableProviders"), variableId)
4502
+ pointer: childPointer$1(childPointer$1(bindingsPointer, "variableProviders"), variableId)
4217
4503
  });
4218
4504
  }
4219
- addImpactCandidates(candidates, agent.affectedBy, childPointer(pointer, "affectedBy"), entity);
4220
- const toolsPointer = childPointer(pointer, "tools");
4505
+ addImpactCandidates(candidates, agent.affectedBy, childPointer$1(pointer, "affectedBy"), entity);
4506
+ const toolsPointer = childPointer$1(pointer, "tools");
4221
4507
  for (const capabilityId of Object.keys(agent.tools ?? {}).sort(compareExactStrings)) {
4222
4508
  const capability = agent.tools?.[capabilityId];
4223
4509
  if (capability !== void 0) addCapabilityCandidates(candidates, capability, "tool", capabilityId, agentId, toolsPointer, [["inputSchema", capability.inputSchema], ["outputSchema", capability.outputSchema]]);
4224
4510
  }
4225
- const skillsPointer = childPointer(pointer, "skills");
4511
+ const skillsPointer = childPointer$1(pointer, "skills");
4226
4512
  for (const capabilityId of Object.keys(agent.skills ?? {}).sort(compareExactStrings)) {
4227
4513
  const capability = agent.skills?.[capabilityId];
4228
4514
  if (capability !== void 0) addCapabilityCandidates(candidates, capability, "skill", capabilityId, agentId, skillsPointer);
4229
4515
  }
4230
- addUnresolvedCandidates(candidates, agent.unresolved, childPointer(pointer, "unresolved"), entity);
4516
+ addUnresolvedCandidates(candidates, agent.unresolved, childPointer$1(pointer, "unresolved"), entity);
4231
4517
  };
4232
4518
  /** Collects every repository-backed manifest declaration in deterministic pointer order. */
4233
4519
  var collectCandidates = (manifest) => {
@@ -4237,7 +4523,7 @@ var collectCandidates = (manifest) => {
4237
4523
  for (const referencedPath of Object.keys(relationships ?? {}).sort(compareExactStrings)) {
4238
4524
  const relationship = relationships?.[referencedPath];
4239
4525
  if (relationship === void 0) continue;
4240
- const pointer = childPointer(`/${property}`, referencedPath);
4526
+ const pointer = childPointer$1(`/${property}`, referencedPath);
4241
4527
  const decisionId = property === "decisions" ? parseDecisionIdFromPath(parseRepositoryPath(referencedPath)) : null;
4242
4528
  addRelationshipCandidates(candidates, relationship, pointer, decisionId === null ? null : { decisionId });
4243
4529
  }
@@ -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, "inspect-project");
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, "inspect-project");
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, "inspect-project");
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.readFile(MANIFEST_PATH, operationOptions),
4722
+ content: await session.reader.readCompleteFile(MANIFEST_PATH, operationOptions),
4437
4723
  path: MANIFEST_PATH
4438
- }, options, "inspect-project");
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-inspection/index.ts
4497
- var isRecord = (candidate) => {
4782
+ //#region src/project-validation/index.ts
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: "inspect-project"
4789
+ operation: "validate-project"
4504
4790
  });
4505
4791
  };
4506
4792
  var isRepositoryReader = (candidate) => {
4507
- return isRecord(candidate) && typeof candidate["getEntry"] === "function" && typeof candidate["listEntries"] === "function" && typeof candidate["readFile"] === "function";
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
- return isRecord(candidate) && typeof candidate["aborted"] === "boolean" && typeof candidate["addEventListener"] === "function" && typeof candidate["removeEventListener"] === "function";
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(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 inspectProject = async (input, options) => {
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,585 @@ 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
- valid: false
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
- diagnostics: availabilityDiagnostics,
4564
- evidence: [],
4565
- formatVersion: universal.formatVersion,
4566
- project: null,
4567
- valid: false
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
- diagnostics: adapterInspection.diagnostics,
4573
- evidence: adapterInspection.evidence,
4574
- formatVersion: universal.formatVersion,
4575
- project: valid ? universal.project : null,
4576
- valid
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
5035
+ });
5036
+ };
5037
+ //#endregion
5038
+ //#region src/scope-matching/validations.ts
5039
+ var isRecord = (value) => {
5040
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5041
+ };
5042
+ /** Throws the stable invalid-argument failure for malformed scope input. */
5043
+ var invalidArgument = () => {
5044
+ throw new CoreOperationException({
5045
+ code: "INVALID_ARGUMENT",
5046
+ operation: "match-manifest-scope"
5047
+ });
5048
+ };
5049
+ /** Throws the stable resource failure for an exhausted scope-input budget. */
5050
+ var resourceLimitExceeded = (limit) => {
5051
+ throw new CoreOperationException({
5052
+ code: "RESOURCE_LIMIT_EXCEEDED",
5053
+ limit,
5054
+ operation: "match-manifest-scope"
5055
+ });
5056
+ };
5057
+ /** Measures scalar UTF-8 bytes without allocating an encoded copy. */
5058
+ var measureUtf8ByteLength = (value) => {
5059
+ let byteLength = 0;
5060
+ for (const scalar of value) {
5061
+ const codePoint = scalar.codePointAt(0) ?? 0;
5062
+ byteLength += codePoint <= 127 ? 1 : codePoint <= 2047 ? 2 : codePoint <= 65535 ? 3 : 4;
5063
+ }
5064
+ return byteLength;
5065
+ };
5066
+ /**
5067
+ * Validates and snapshots one public manifest-scope input.
5068
+ * @param input The untrusted manifest document and changed logical paths.
5069
+ * @param limits The immutable Core resource limits.
5070
+ * @returns The detached manifest input and sorted unique repository paths.
5071
+ * @throws
5072
+ * - INVALID_REPOSITORY_PATH: A changed repository path is invalid.
5073
+ * - INVALID_ARGUMENT: The scope operation received an invalid argument.
5074
+ * - RESOURCE_LIMIT_EXCEEDED: The changed-path count or byte budget was exceeded.
5075
+ */
5076
+ var normalizeManifestScopeInput = (input, limits) => {
5077
+ if (!isRecord(input)) return invalidArgument();
5078
+ const manifest = input["manifest"];
5079
+ const pathCandidates = input["paths"];
5080
+ if (!isRecord(manifest) || !Array.isArray(pathCandidates)) return invalidArgument();
5081
+ if (pathCandidates.length > limits.maxEntries) return resourceLimitExceeded("maxEntries");
5082
+ const uniquePaths = /* @__PURE__ */ new Set();
5083
+ let totalBytes = 0;
5084
+ for (const [index, candidate] of pathCandidates.entries()) {
5085
+ if (typeof candidate !== "string") return invalidArgument();
5086
+ const path = parseRepositoryPath(candidate);
5087
+ totalBytes += measureUtf8ByteLength(path) + (index === 0 ? 0 : 1);
5088
+ if (totalBytes > limits.maxTotalBytesRead) return resourceLimitExceeded("maxTotalBytesRead");
5089
+ uniquePaths.add(path);
5090
+ }
5091
+ return {
5092
+ manifest,
5093
+ paths: [...uniquePaths].sort(compareExactStrings)
5094
+ };
5095
+ };
5096
+ //#endregion
5097
+ //#region src/scope-matching/matching.ts
5098
+ var childPointer = (pointer, segment) => {
5099
+ return `${pointer}/${escapeJsonPointerSegment(segment)}`;
5100
+ };
5101
+ var createOwner = (kind, id, agentId = null) => ({
5102
+ agentId,
5103
+ id,
5104
+ kind
5105
+ });
5106
+ var compareOwners = (left, right) => {
5107
+ return compareExactStrings(left.kind, right.kind) || compareExactStrings(left.agentId ?? "", right.agentId ?? "") || compareExactStrings(left.id, right.id);
5108
+ };
5109
+ var getDeclarationValue = (declaration) => {
5110
+ return declaration.kind === "exact" ? declaration.path : declaration.pattern;
5111
+ };
5112
+ var compareDeclarations = (left, right) => {
5113
+ return compareOwners(left.owner, right.owner) || compareExactStrings(left.field, right.field) || compareExactStrings(getDeclarationValue(left.declaration), getDeclarationValue(right.declaration)) || compareExactStrings(left.pointer, right.pointer);
5114
+ };
5115
+ /** Adds one exact repository relationship to the normalized declaration collection. */
5116
+ var addExactDeclaration = (declarations, owner, field, pointer, reference) => {
5117
+ declarations.push({
5118
+ declaration: typeof reference === "string" ? {
5119
+ kind: "exact",
5120
+ path: reference,
5121
+ symbol: null
5122
+ } : {
5123
+ kind: "exact",
5124
+ path: reference.path,
5125
+ symbol: reference.symbol ?? null
5126
+ },
5127
+ field,
5128
+ owner,
5129
+ pointer
5130
+ });
5131
+ };
5132
+ /** Adds sorted repository references while preserving normalized declaration pointers. */
5133
+ var addReferenceDeclarations = (declarations, references, owner, field, pointer) => {
5134
+ for (const [index, reference] of (references ?? []).entries()) addExactDeclaration(declarations, owner, field, childPointer(pointer, String(index)), reference);
5135
+ };
5136
+ /** Adds exact and simple-glob impact relationships in normalized array order. */
5137
+ var addAffectedByDeclarations = (declarations, affectedBy, owner, pointer) => {
5138
+ for (const [index, pattern] of (affectedBy ?? []).entries()) declarations.push({
5139
+ declaration: pattern.includes("*") ? {
5140
+ kind: "glob",
5141
+ pattern
5142
+ } : {
5143
+ kind: "exact",
5144
+ path: pattern,
5145
+ symbol: null
5146
+ },
5147
+ field: "affectedBy",
5148
+ owner,
5149
+ pointer: childPointer(pointer, String(index))
5150
+ });
5151
+ };
5152
+ /** Adds project-level or agent-level unresolved requirement references. */
5153
+ var addUnresolvedDeclarations = (declarations, requirements, pointer, agentId) => {
5154
+ for (const requirementId of Object.keys(requirements ?? {}).sort(compareExactStrings)) {
5155
+ const requirement = requirements?.[requirementId];
5156
+ if (requirement === void 0) continue;
5157
+ const owner = createOwner("unresolved", requirementId, agentId);
5158
+ addReferenceDeclarations(declarations, requirement.related, owner, "related", childPointer(childPointer(pointer, requirementId), "related"));
5159
+ }
5160
+ };
5161
+ /** Adds exact and impact declarations owned by one tool or skill capability. */
5162
+ var addCapabilityDeclarations = (declarations, capabilityId, capability, agentId, pointer) => {
5163
+ const owner = createOwner(capability.kind, capabilityId, agentId);
5164
+ addExactDeclaration(declarations, owner, "implementation", childPointer(pointer, "implementation"), capability.value.implementation);
5165
+ if (capability.value.registration !== void 0) addExactDeclaration(declarations, owner, "registration", childPointer(pointer, "registration"), capability.value.registration);
5166
+ if (capability.kind === "tool") for (const field of ["inputSchema", "outputSchema"]) {
5167
+ const reference = capability.value[field];
5168
+ if (reference !== void 0) addExactDeclaration(declarations, owner, field, childPointer(pointer, field), reference);
5169
+ }
5170
+ addAffectedByDeclarations(declarations, capability.value.affectedBy, owner, childPointer(pointer, "affectedBy"));
5171
+ };
5172
+ /** Adds all exact and impact relationships owned by one registered agent. */
5173
+ var addAgentDeclarations = (declarations, agentId, agent) => {
5174
+ const pointer = childPointer("/agents", agentId);
5175
+ const owner = createOwner("agent", agentId, agentId);
5176
+ const bindingsPointer = childPointer(pointer, "bindings");
5177
+ for (const field of [
5178
+ "runtimeAgent",
5179
+ "inputSchema",
5180
+ "outputSchema",
5181
+ "instructionLoader"
5182
+ ]) {
5183
+ const reference = agent.bindings?.[field];
5184
+ if (reference !== void 0) addExactDeclaration(declarations, owner, field, childPointer(bindingsPointer, field), reference);
5185
+ }
5186
+ for (const variableId of Object.keys(agent.bindings?.variableProviders ?? {}).sort(compareExactStrings)) {
5187
+ const reference = agent.bindings?.variableProviders?.[variableId];
5188
+ if (reference !== void 0) addExactDeclaration(declarations, owner, "variableProvider", childPointer(childPointer(bindingsPointer, "variableProviders"), variableId), reference);
5189
+ }
5190
+ addAffectedByDeclarations(declarations, agent.affectedBy, owner, childPointer(pointer, "affectedBy"));
5191
+ for (const capabilityId of Object.keys(agent.tools ?? {}).sort(compareExactStrings)) {
5192
+ const tool = agent.tools?.[capabilityId];
5193
+ if (tool !== void 0) addCapabilityDeclarations(declarations, capabilityId, {
5194
+ kind: "tool",
5195
+ value: tool
5196
+ }, agentId, childPointer(childPointer(pointer, "tools"), capabilityId));
5197
+ }
5198
+ for (const capabilityId of Object.keys(agent.skills ?? {}).sort(compareExactStrings)) {
5199
+ const skill = agent.skills?.[capabilityId];
5200
+ if (skill !== void 0) addCapabilityDeclarations(declarations, capabilityId, {
5201
+ kind: "skill",
5202
+ value: skill
5203
+ }, agentId, childPointer(childPointer(pointer, "skills"), capabilityId));
5204
+ }
5205
+ for (const [index, mirror] of (agent.mirrors ?? []).entries()) addExactDeclaration(declarations, owner, "mirrors", childPointer(childPointer(pointer, "mirrors"), String(index)), mirror);
5206
+ addUnresolvedDeclarations(declarations, agent.unresolved, childPointer(pointer, "unresolved"), agentId);
5207
+ };
5208
+ /** Collects every version 1 declaration that can establish changed-path relevance. */
5209
+ var collectDeclarations = (manifest) => {
5210
+ const declarations = [];
5211
+ for (const kind of ["context", "decision"]) {
5212
+ const relationships = kind === "context" ? manifest.context : manifest.decisions;
5213
+ for (const ownerId of Object.keys(relationships ?? {}).sort(compareExactStrings)) {
5214
+ const relationship = relationships?.[ownerId];
5215
+ if (relationship === void 0) continue;
5216
+ const owner = createOwner(kind, ownerId);
5217
+ const pointer = childPointer(kind === "context" ? "/context" : "/decisions", ownerId);
5218
+ addReferenceDeclarations(declarations, relationship.bindings, owner, "bindings", childPointer(pointer, "bindings"));
5219
+ addAffectedByDeclarations(declarations, relationship.affectedBy, owner, childPointer(pointer, "affectedBy"));
5220
+ }
5221
+ }
5222
+ addUnresolvedDeclarations(declarations, manifest.unresolved, "/unresolved", null);
5223
+ for (const agentId of Object.keys(manifest.agents ?? {}).sort(compareExactStrings)) {
5224
+ const agent = manifest.agents?.[agentId];
5225
+ if (agent !== void 0) addAgentDeclarations(declarations, agentId, agent);
5226
+ }
5227
+ return declarations.sort(compareDeclarations);
5228
+ };
5229
+ /** Tests a single-segment wildcard without regular-expression interpretation. */
5230
+ var matchesSegment = (pattern, value) => {
5231
+ let patternIndex = 0;
5232
+ let valueIndex = 0;
5233
+ let starIndex = -1;
5234
+ let starValueIndex = -1;
5235
+ while (valueIndex < value.length) {
5236
+ if (pattern[patternIndex] === value[valueIndex]) {
5237
+ patternIndex += 1;
5238
+ valueIndex += 1;
5239
+ continue;
5240
+ }
5241
+ if (pattern[patternIndex] === "*") {
5242
+ starIndex = patternIndex;
5243
+ starValueIndex = valueIndex;
5244
+ patternIndex += 1;
5245
+ continue;
5246
+ }
5247
+ if (starIndex === -1) return false;
5248
+ patternIndex = starIndex + 1;
5249
+ starValueIndex += 1;
5250
+ valueIndex = starValueIndex;
5251
+ }
5252
+ while (pattern[patternIndex] === "*") patternIndex += 1;
5253
+ return patternIndex === pattern.length;
5254
+ };
5255
+ /** Matches validated simple-glob segments with zero-or-more-segment globstars. */
5256
+ var matchesGlob = (patternSegments, path) => {
5257
+ const pathSegments = path.slice(1).split("/");
5258
+ let reachable = new Uint8Array(pathSegments.length + 1);
5259
+ reachable[0] = 1;
5260
+ for (const patternSegment of patternSegments) {
5261
+ const next = new Uint8Array(pathSegments.length + 1);
5262
+ if (patternSegment === "**") {
5263
+ let canReach = false;
5264
+ for (let index = 0; index < reachable.length; index += 1) {
5265
+ canReach ||= reachable[index] === 1;
5266
+ next[index] = canReach ? 1 : 0;
5267
+ }
5268
+ } else for (let index = 0; index < pathSegments.length; index += 1) if (reachable[index] === 1 && matchesSegment(patternSegment, pathSegments[index] ?? "")) next[index + 1] = 1;
5269
+ reachable = next;
5270
+ }
5271
+ return reachable[pathSegments.length] === 1;
5272
+ };
5273
+ /** Builds exact and first-segment glob indexes once for one parsed manifest. */
5274
+ var compileManifestScope = (manifest, limits) => {
5275
+ const declarations = collectDeclarations(manifest);
5276
+ if (declarations.length > limits.maxEntries) throw new CoreOperationException({
5277
+ code: "RESOURCE_LIMIT_EXCEEDED",
5278
+ limit: "maxEntries",
5279
+ operation: "match-manifest-scope"
5280
+ });
5281
+ const exact = /* @__PURE__ */ new Map();
5282
+ const globalGlobs = [];
5283
+ const globsByFirstSegment = /* @__PURE__ */ new Map();
5284
+ for (const declaration of declarations) {
5285
+ if (declaration.declaration.kind === "exact") {
5286
+ const existing = exact.get(declaration.declaration.path) ?? [];
5287
+ existing.push(declaration);
5288
+ exact.set(declaration.declaration.path, existing);
5289
+ continue;
5290
+ }
5291
+ const segments = declaration.declaration.pattern.slice(1).split("/");
5292
+ const compiled = {
5293
+ declaration,
5294
+ segments
5295
+ };
5296
+ const firstSegment = segments[0] ?? "";
5297
+ if (firstSegment === "**" || firstSegment.includes("*")) globalGlobs.push(compiled);
5298
+ else {
5299
+ const existing = globsByFirstSegment.get(firstSegment) ?? [];
5300
+ existing.push(compiled);
5301
+ globsByFirstSegment.set(firstSegment, existing);
5302
+ }
5303
+ }
5304
+ return {
5305
+ declarations,
5306
+ exact,
5307
+ globalGlobs,
5308
+ globsByFirstSegment
5309
+ };
5310
+ };
5311
+ var compareMatches = (left, right) => {
5312
+ 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);
5313
+ };
5314
+ var createMatch = (inputPath, relationship) => ({
5315
+ declaration: relationship.declaration,
5316
+ field: relationship.field,
5317
+ inputPath,
5318
+ owner: relationship.owner,
5319
+ pointer: relationship.pointer
5320
+ });
5321
+ /** Adds one match without ever allocating beyond the operation entry budget. */
5322
+ var addMatch = (matches, inputPath, relationship, limits) => {
5323
+ if (matches.length >= limits.maxEntries) throw new CoreOperationException({
5324
+ code: "RESOURCE_LIMIT_EXCEEDED",
5325
+ limit: "maxEntries",
5326
+ operation: "match-manifest-scope"
5327
+ });
5328
+ matches.push(createMatch(inputPath, relationship));
5329
+ };
5330
+ /** Appends matches from one precompiled glob bucket without copying the bucket. */
5331
+ var addGlobMatches = (matches, inputPath, declarations, limits) => {
5332
+ for (const compiled of declarations) if (matchesGlob(compiled.segments, inputPath)) addMatch(matches, inputPath, compiled.declaration, limits);
5333
+ };
5334
+ /** Creates the canonical digest of the sorted unique changed-path set. */
5335
+ var calculateManifestScopeInputDigest = async (paths) => {
5336
+ const value = paths.join("\0");
5337
+ return calculateNormalizedTextDigest({
5338
+ scalarLength: countUnicodeScalars$1(value),
5339
+ utf8ByteLength: measureUtf8ByteLength(value),
5340
+ value
5341
+ });
5342
+ };
5343
+ /**
5344
+ * Matches normalized changed paths against one valid version 1 manifest.
5345
+ * @param manifest The parsed and validated manifest value.
5346
+ * @param paths Sorted unique repository-logical changed paths.
5347
+ * @param limits The immutable Core operation limits.
5348
+ * @returns Frozen content-free matches and stable aggregate counts.
5349
+ * @throws
5350
+ * - RESOURCE_LIMIT_EXCEEDED: The declaration or match count exceeded `maxEntries`.
5351
+ */
5352
+ var matchParsedManifestScope = (manifest, paths, limits) => {
5353
+ const compiled = compileManifestScope(manifest, limits);
5354
+ const matches = [];
5355
+ const matchedOwners = /* @__PURE__ */ new Set();
5356
+ const matchedPaths = /* @__PURE__ */ new Set();
5357
+ for (const path of paths) {
5358
+ const firstSegment = path.slice(1).split("/", 1)[0] ?? "";
5359
+ const exactDeclarations = compiled.exact.get(path) ?? [];
5360
+ for (const relationship of exactDeclarations) addMatch(matches, path, relationship, limits);
5361
+ addGlobMatches(matches, path, compiled.globalGlobs, limits);
5362
+ addGlobMatches(matches, path, compiled.globsByFirstSegment.get(firstSegment) ?? [], limits);
5363
+ }
5364
+ matches.sort(compareMatches);
5365
+ for (const match of matches) {
5366
+ matchedOwners.add(`${match.owner.kind}\0${match.owner.agentId ?? ""}\0${match.owner.id}`);
5367
+ matchedPaths.add(match.inputPath);
5368
+ }
5369
+ return freezeRecursively({
5370
+ counts: {
5371
+ declarations: compiled.declarations.length,
5372
+ inputPaths: paths.length,
5373
+ matchedOwners: matchedOwners.size,
5374
+ matchedPaths: matchedPaths.size,
5375
+ matches: matches.length
5376
+ },
5377
+ matches
5378
+ });
5379
+ };
5380
+ //#endregion
5381
+ //#region src/scope-matching/scope.ts
5382
+ /**
5383
+ * Parses a manifest and matches its repository relationships against changed logical paths.
5384
+ * @param input The canonical manifest document and untrusted changed-path collection.
5385
+ * @param options The immutable Core operation options.
5386
+ * @returns A promise resolving to frozen content-free scope metadata and matches.
5387
+ * @throws
5388
+ * - INVALID_REPOSITORY_PATH: The manifest path or a changed repository path is invalid.
5389
+ * - INVALID_ARGUMENT: The scope operation received an invalid argument.
5390
+ * - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
5391
+ */
5392
+ var matchManifestScope = async (input, options) => {
5393
+ const normalized = normalizeManifestScopeInput(input, options.limits);
5394
+ const inputDigest = await calculateManifestScopeInputDigest(normalized.paths);
5395
+ const parsed = await parseManifestDocument(normalized.manifest, options, "match-manifest-scope");
5396
+ if (!parsed.valid || parsed.asset === null || parsed.manifest === null) return freezeRecursively({
5397
+ counts: {
5398
+ declarations: 0,
5399
+ inputPaths: normalized.paths.length,
5400
+ matchedOwners: 0,
5401
+ matchedPaths: 0,
5402
+ matches: 0
5403
+ },
5404
+ diagnostics: parsed.diagnostics,
5405
+ inputDigest,
5406
+ manifestDigest: null,
5407
+ matches: [],
5408
+ relevant: false,
5409
+ valid: false
5410
+ });
5411
+ const matched = matchParsedManifestScope(parsed.manifest, normalized.paths, options.limits);
5412
+ return freezeRecursively({
5413
+ counts: matched.counts,
5414
+ diagnostics: [],
5415
+ inputDigest,
5416
+ manifestDigest: parsed.asset.digest,
5417
+ matches: matched.matches,
5418
+ relevant: matched.matches.length > 0,
5419
+ valid: true
4577
5420
  });
4578
5421
  };
4579
5422
  //#endregion
@@ -4594,12 +5437,15 @@ var createCore = (options) => {
4594
5437
  calculateContentDigest: (input) => {
4595
5438
  return calculateContentDigest(input, createCoreOperationOptionsSnapshot(snapshot).limits);
4596
5439
  },
4597
- inspectProject: (input) => inspectProject(input, createCoreOperationOptionsSnapshot(snapshot)),
5440
+ inspectProjectPage: (input) => inspectProjectPage(input, createCoreOperationOptionsSnapshot(snapshot)),
5441
+ validateProject: (input) => validateProject(input, createCoreOperationOptionsSnapshot(snapshot)),
5442
+ matchManifestScope: (input) => matchManifestScope(input, createCoreOperationOptionsSnapshot(snapshot)),
4598
5443
  normalizeText: (input) => {
4599
5444
  return normalizeTextDocument(input, createCoreOperationOptionsSnapshot(snapshot).limits, "normalize-text");
4600
5445
  },
4601
5446
  parseDecision: (input) => parseDecisionDocument(input, createCoreOperationOptionsSnapshot(snapshot)),
4602
- parseManifest: (input) => parseManifestDocument(input, createCoreOperationOptionsSnapshot(snapshot))
5447
+ parseManifest: (input) => parseManifestDocument(input, createCoreOperationOptionsSnapshot(snapshot)),
5448
+ readCanonicalContentPage: (input) => readCanonicalContentPage(input, createCoreOperationOptionsSnapshot(snapshot))
4603
5449
  });
4604
5450
  };
4605
5451
  //#endregion