@moldea.ai/core 7.0.3 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/analysis-worker.js +40 -10
- package/dist/analysis-worker.js.map +1 -1
- package/dist/chunks/{core-DC9KYL1H.js → core-CMuQrqRI.js} +395 -64
- package/dist/chunks/core-CMuQrqRI.js.map +1 -0
- package/dist/chunks/{errors-Dw1ahMS1.js → errors-BhiLG9F0.js} +20 -4
- package/dist/chunks/errors-BhiLG9F0.js.map +1 -0
- package/dist/chunks/{lifecycle-h3DWn5vl.js → lifecycle-Bdi_ydtH.js} +2 -2
- package/dist/chunks/{lifecycle-h3DWn5vl.js.map → lifecycle-Bdi_ydtH.js.map} +1 -1
- package/dist/chunks/{options-AMqX7rx_.js → options-BVF3DQHm.js} +7 -3
- package/dist/chunks/options-BVF3DQHm.js.map +1 -0
- package/dist/chunks/{repository-rpc-ClAIx3-c.js → repository-rpc-CiKFu86B.js} +70 -16
- package/dist/chunks/repository-rpc-CiKFu86B.js.map +1 -0
- package/dist/chunks/{scope-DxhC1hq2.js → scope-DoNl6LhC.js} +3 -3
- package/dist/chunks/scope-DoNl6LhC.js.map +1 -0
- package/dist/constants/index.d.ts +1 -1
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +7 -2
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/diagnostic-utilities/index.d.ts.map +1 -1
- package/dist/diagnostics/index.d.ts +2 -2
- package/dist/diagnostics/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/integration-validation/agents-inspection.d.ts +19 -0
- package/dist/integration-validation/agents-inspection.d.ts.map +1 -0
- package/dist/integration-validation/claude-inspection.d.ts +21 -0
- package/dist/integration-validation/claude-inspection.d.ts.map +1 -0
- package/dist/integration-validation/inspection.d.ts +9 -3
- package/dist/integration-validation/inspection.d.ts.map +1 -1
- package/dist/integration-validation/parser.d.ts +8 -0
- package/dist/integration-validation/parser.d.ts.map +1 -1
- package/dist/integration-validation/types.d.ts +18 -0
- package/dist/integration-validation/types.d.ts.map +1 -1
- package/dist/integration-validation/utilities.d.ts +33 -0
- package/dist/integration-validation/utilities.d.ts.map +1 -0
- package/dist/node-inspection/client.d.ts.map +1 -1
- package/dist/node-inspection/protocol.d.ts.map +1 -1
- package/dist/node-inspection/repository-rpc.d.ts +7 -5
- package/dist/node-inspection/repository-rpc.d.ts.map +1 -1
- package/dist/node-inspection/types.d.ts +22 -1
- package/dist/node-inspection/types.d.ts.map +1 -1
- package/dist/node-runner.js +2 -2
- package/dist/node.js +37 -10
- package/dist/node.js.map +1 -1
- package/dist/project-validation/index.d.ts +1 -1
- package/dist/project-validation/index.d.ts.map +1 -1
- package/dist/repository-inspection-session/index.d.ts +12 -3
- package/dist/repository-inspection-session/index.d.ts.map +1 -1
- package/dist/retained-memory/index.d.ts +5 -4
- package/dist/retained-memory/index.d.ts.map +1 -1
- package/dist/scope.js +2 -2
- package/dist/universal-project-inspection/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/chunks/core-DC9KYL1H.js.map +0 -1
- package/dist/chunks/errors-Dw1ahMS1.js.map +0 -1
- package/dist/chunks/options-AMqX7rx_.js.map +0 -1
- package/dist/chunks/repository-rpc-ClAIx3-c.js.map +0 -1
- package/dist/chunks/scope-DxhC1hq2.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { E as parseDecisionIdFromPath, O as trimRepositoryFormatWhitespace, S as isRuntimeGuidancePath, T as isVariableId, a as escapeJsonPointerSegment, c as freezeRecursively, d as hasNonWhitespace, g as isContextPath, i as createCoreDiagnosticCollector, l as compareExactStrings, n as normalizeCoreOptions, o as normalizeDiagnostics, r as countDiagnosticsBySeverity, s as createNullPrototypeRecord, t as createCoreOperationOptionsSnapshot, u as countUnicodeScalars } from "./options-
|
|
1
|
+
import { E as parseDecisionIdFromPath, O as trimRepositoryFormatWhitespace, S as isRuntimeGuidancePath, T as isVariableId, a as escapeJsonPointerSegment, c as freezeRecursively, d as hasNonWhitespace, g as isContextPath, i as createCoreDiagnosticCollector, l as compareExactStrings, n as normalizeCoreOptions, o as normalizeDiagnostics, r as countDiagnosticsBySeverity, s as createNullPrototypeRecord, t as createCoreOperationOptionsSnapshot, u as countUnicodeScalars } from "./options-BVF3DQHm.js";
|
|
2
2
|
import { n as CoreOperationException } from "./exceptions-CYf1pCKf.js";
|
|
3
|
-
import { a as createSourceLocator, c as calculateContentDigest, i as parseStrictYaml, l as calculateNormalizedTextDigest, n as inspectManifestDocument, o as collectManifestScopeDeclarations, r as parseManifestDocument, s as matchesRepositoryGlob, t as matchManifestScope, u as normalizeTextDocument } from "./scope-
|
|
3
|
+
import { a as createSourceLocator, c as calculateContentDigest, i as parseStrictYaml, l as calculateNormalizedTextDigest, n as inspectManifestDocument, o as collectManifestScopeDeclarations, r as parseManifestDocument, s as matchesRepositoryGlob, t as matchManifestScope, u as normalizeTextDocument } from "./scope-DoNl6LhC.js";
|
|
4
4
|
import { REPOSITORY_ROOT, RepositorySourceException, compareRepositoryPaths, createRepositoryIdentity, isRepositoryPath, parseRepositoryPath } from "@moldea.ai/repository";
|
|
5
5
|
//#region \0rolldown/runtime.js
|
|
6
6
|
var __defProp = Object.defineProperty;
|
|
@@ -495,6 +495,12 @@ var reserveRetainedBytesIfTracked = (reader, bytes) => {
|
|
|
495
495
|
//#endregion
|
|
496
496
|
//#region src/repository-inspection-session/index.ts
|
|
497
497
|
var MANIFEST_PATH$3 = parseRepositoryPath("/moldea/moldea.yaml");
|
|
498
|
+
var INSTRUCTION_PATHS = new Set([
|
|
499
|
+
"/AGENTS.md",
|
|
500
|
+
"/CLAUDE.md",
|
|
501
|
+
"/.claude/CLAUDE.md",
|
|
502
|
+
"/CLAUDE.local.md"
|
|
503
|
+
].map((path) => parseRepositoryPath(path)));
|
|
498
504
|
var SOURCE_PAGE_ENTRIES = 256;
|
|
499
505
|
var SOURCE_PAGE_BYTES = 65536;
|
|
500
506
|
var CANONICAL_BYTE_RETENTION_MULTIPLIER = 4;
|
|
@@ -528,6 +534,41 @@ var copyReaderEntry$1 = (candidate, operation, fallbackPath, expectedPath) => {
|
|
|
528
534
|
type: typeCandidate
|
|
529
535
|
};
|
|
530
536
|
};
|
|
537
|
+
var REFUSED_LINK_STATES = [
|
|
538
|
+
"broken",
|
|
539
|
+
"denied",
|
|
540
|
+
"loop",
|
|
541
|
+
"unsafe"
|
|
542
|
+
];
|
|
543
|
+
var LINK_TARGET_TYPES = [
|
|
544
|
+
"directory",
|
|
545
|
+
"file",
|
|
546
|
+
"other"
|
|
547
|
+
];
|
|
548
|
+
/** Copies one untrusted link resolution, rejecting any shape outside the closed contract. */
|
|
549
|
+
var copyLinkResolution = (candidate, path) => {
|
|
550
|
+
if (typeof candidate !== "object" || candidate === null) return invalidSourceData$3("get-entry", path);
|
|
551
|
+
const record = candidate;
|
|
552
|
+
const keys = Object.keys(record).sort().join();
|
|
553
|
+
const refusedState = REFUSED_LINK_STATES.find((state) => state === record["state"]);
|
|
554
|
+
if (Reflect.ownKeys(record).length !== Object.keys(record).length) return invalidSourceData$3("get-entry", path);
|
|
555
|
+
if (record["state"] === "not-link" || refusedState !== void 0) return keys === "state" ? { state: refusedState ?? "not-link" } : invalidSourceData$3("get-entry", path);
|
|
556
|
+
const targetIdentity = record["targetIdentity"];
|
|
557
|
+
const targetType = LINK_TARGET_TYPES.find((type) => type === record["targetType"]);
|
|
558
|
+
if (typeof targetIdentity !== "string" || targetIdentity.length === 0 || targetType === void 0) return invalidSourceData$3("get-entry", path);
|
|
559
|
+
if (record["state"] === "outside" && keys === "state,targetIdentity,targetType") return {
|
|
560
|
+
state: "outside",
|
|
561
|
+
targetIdentity,
|
|
562
|
+
targetType
|
|
563
|
+
};
|
|
564
|
+
const targetPath = record["targetPath"];
|
|
565
|
+
return record["state"] === "inside" && keys === "state,targetIdentity,targetPath,targetType" && typeof targetPath === "string" && isRepositoryPath(targetPath) ? {
|
|
566
|
+
state: "inside",
|
|
567
|
+
targetIdentity,
|
|
568
|
+
targetPath: parseRepositoryPath(targetPath),
|
|
569
|
+
targetType
|
|
570
|
+
} : invalidSourceData$3("get-entry", path);
|
|
571
|
+
};
|
|
531
572
|
var isStrictDescendant = (path, prefix) => {
|
|
532
573
|
if (path === prefix) return false;
|
|
533
574
|
const descendantPrefix = prefix === REPOSITORY_ROOT ? REPOSITORY_ROOT : `${prefix}/`;
|
|
@@ -552,11 +593,12 @@ var createSourceOptions = (sessionSignal, operationSignal) => {
|
|
|
552
593
|
* @param repository The source-neutral reader bound to one coherent snapshot.
|
|
553
594
|
* @param limits The immutable resource limits for the inspection.
|
|
554
595
|
* @param signal Optional cancellation shared by every inspection operation.
|
|
596
|
+
* @param instructions Optional instruction source read only through the instruction view.
|
|
555
597
|
* @returns A session that pages source metadata and range-reads bounded canonical files.
|
|
556
598
|
* @throws
|
|
557
599
|
* - ABORTED: The Core operation was aborted.
|
|
558
600
|
*/
|
|
559
|
-
var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
601
|
+
var createRepositoryInspectionSession = (repository, limits, signal, instructions) => {
|
|
560
602
|
const seenPaths = /* @__PURE__ */ new Set();
|
|
561
603
|
let canonicalBytes = 0;
|
|
562
604
|
let peakRetainedBytes = 0;
|
|
@@ -593,14 +635,19 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
593
635
|
if (byteLength > limits.maxTotalBytesRead - totalBytesRead) return throwResourceLimitExceeded("maxTotalBytesRead", limits.maxTotalBytesRead, totalBytesRead + byteLength);
|
|
594
636
|
totalBytesRead += byteLength;
|
|
595
637
|
};
|
|
596
|
-
const
|
|
638
|
+
const repositoryPages = {
|
|
639
|
+
readPage: (path, options) => repository.readFilePage(path, options),
|
|
640
|
+
snapshotId: repository.snapshot.id
|
|
641
|
+
};
|
|
642
|
+
const getEntryFrom = async (source, path, options) => {
|
|
597
643
|
const parsedPath = parseRepositoryPath(path);
|
|
598
644
|
throwIfSignalAborted(options?.signal);
|
|
599
645
|
registerPath(parsedPath);
|
|
600
|
-
const candidate = await
|
|
646
|
+
const candidate = await source.getEntry(parsedPath, createSourceOptions(signal, options?.signal));
|
|
601
647
|
throwIfSignalAborted(options?.signal);
|
|
602
648
|
return candidate === null ? null : copyReaderEntry$1(candidate, "get-entry", parsedPath, parsedPath);
|
|
603
649
|
};
|
|
650
|
+
const getEntry = (path, options) => getEntryFrom(repository, path, options);
|
|
604
651
|
const iterateEntries = (options) => {
|
|
605
652
|
const prefix = options?.prefix === void 0 ? REPOSITORY_ROOT : parseRepositoryPath(options.prefix);
|
|
606
653
|
return { async *[Symbol.asyncIterator]() {
|
|
@@ -635,20 +682,20 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
635
682
|
} while (true);
|
|
636
683
|
} };
|
|
637
684
|
};
|
|
638
|
-
const loadFile = async (path, operationSignal, isSource = false) => {
|
|
685
|
+
const loadFile = async (path, operationSignal, isSource = false, pages = repositoryPages) => {
|
|
639
686
|
const multiplier = isSource ? 1 : CANONICAL_BYTE_RETENTION_MULTIPLIER;
|
|
640
687
|
const fileLimit = path === MANIFEST_PATH$3 ? "maxManifestBytes" : "maxFileBytes";
|
|
641
688
|
const availableRetainedBytes = limits.maxRetainedBytes - retainedBytes;
|
|
642
689
|
if (availableRetainedBytes < 1) return throwResourceLimitExceeded("maxRetainedBytes", limits.maxRetainedBytes, retainedBytes + 1);
|
|
643
690
|
const firstPageMaximumBytes = Math.min(SOURCE_PAGE_BYTES, Math.max(1, limits[fileLimit]), availableRetainedBytes);
|
|
644
691
|
observeTransientBytes(firstPageMaximumBytes);
|
|
645
|
-
const firstPage = await
|
|
692
|
+
const firstPage = await pages.readPage(path, {
|
|
646
693
|
maxBytes: firstPageMaximumBytes,
|
|
647
694
|
offset: 0,
|
|
648
695
|
...createSourceOptions(signal, operationSignal) ?? {}
|
|
649
696
|
});
|
|
650
697
|
throwIfSignalAborted(operationSignal);
|
|
651
|
-
if (firstPage.snapshot.id !==
|
|
698
|
+
if (firstPage.snapshot.id !== pages.snapshotId || 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);
|
|
652
699
|
if (firstPage.totalBytes > limits[fileLimit]) return throwResourceLimitExceeded(fileLimit, limits[fileLimit], firstPage.totalBytes);
|
|
653
700
|
const firstPageBytes = firstPage.bytes.byteLength;
|
|
654
701
|
const retainedBytesAvailableForCanonicalContent = limits.maxRetainedBytes - retainedBytes - firstPageBytes;
|
|
@@ -667,7 +714,7 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
667
714
|
let isFirstPage = true;
|
|
668
715
|
while (isFirstPage || offset < content.byteLength) {
|
|
669
716
|
isFirstPage = false;
|
|
670
|
-
if (page.snapshot.id !==
|
|
717
|
+
if (page.snapshot.id !== pages.snapshotId || 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);
|
|
671
718
|
content.set(page.bytes, offset);
|
|
672
719
|
offset += page.bytes.byteLength;
|
|
673
720
|
if (page.isComplete) {
|
|
@@ -675,7 +722,7 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
675
722
|
break;
|
|
676
723
|
}
|
|
677
724
|
if (page.nextOffset !== offset) return invalidSourceData$3("read-file-page", path);
|
|
678
|
-
page = await
|
|
725
|
+
page = await pages.readPage(path, {
|
|
679
726
|
maxBytes: Math.min(SOURCE_PAGE_BYTES, Math.max(1, content.byteLength - offset)),
|
|
680
727
|
offset,
|
|
681
728
|
...createSourceOptions(signal, operationSignal) ?? {}
|
|
@@ -718,6 +765,53 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
718
765
|
throwIfSignalAborted(options?.signal);
|
|
719
766
|
return content.slice();
|
|
720
767
|
};
|
|
768
|
+
/** Loads one complete temporary source buffer whose reservation the caller releases. */
|
|
769
|
+
const readRetainedSource = async (path, pages) => {
|
|
770
|
+
throwIfSignalAborted();
|
|
771
|
+
registerPath(path);
|
|
772
|
+
const bytes = await awaitWithCancellation(loadFile(path, void 0, true, pages));
|
|
773
|
+
throwIfSignalAborted();
|
|
774
|
+
let isReleased = false;
|
|
775
|
+
return {
|
|
776
|
+
bytes,
|
|
777
|
+
release: () => {
|
|
778
|
+
if (!isReleased) retainedBytes -= bytes.byteLength;
|
|
779
|
+
isReleased = true;
|
|
780
|
+
}
|
|
781
|
+
};
|
|
782
|
+
};
|
|
783
|
+
const instructionReader = instructions?.reader ?? repository;
|
|
784
|
+
const instructionPages = instructions === void 0 ? repositoryPages : {
|
|
785
|
+
readPage: (path, options) => instructions.reader.readFilePage(path, options),
|
|
786
|
+
snapshotId: instructions.reader.snapshot.id
|
|
787
|
+
};
|
|
788
|
+
const linkResolver = instructions?.linkResolver;
|
|
789
|
+
const linkPages = linkResolver === void 0 ? void 0 : {
|
|
790
|
+
readPage: (path, options) => linkResolver.readLinkTargetPage(path, options),
|
|
791
|
+
snapshotId: linkResolver.snapshot.id
|
|
792
|
+
};
|
|
793
|
+
const requireInstructionPath = (path) => {
|
|
794
|
+
const parsedPath = parseRepositoryPath(path);
|
|
795
|
+
if (!INSTRUCTION_PATHS.has(parsedPath)) throw new TypeError("The instruction view reads only coding-agent instruction paths.");
|
|
796
|
+
return parsedPath;
|
|
797
|
+
};
|
|
798
|
+
const instructionView = Object.freeze({
|
|
799
|
+
getEntry: (path) => getEntryFrom(instructionReader, requireInstructionPath(path)),
|
|
800
|
+
readLinkedSourceFile: (path) => {
|
|
801
|
+
if (linkPages === void 0) throw new TypeError("The instruction view has no link resolver to read through.");
|
|
802
|
+
return readRetainedSource(requireInstructionPath(path), linkPages);
|
|
803
|
+
},
|
|
804
|
+
readSourceFile: (path) => readRetainedSource(requireInstructionPath(path), instructionPages),
|
|
805
|
+
resolveLink: async (path) => {
|
|
806
|
+
const parsedPath = requireInstructionPath(path);
|
|
807
|
+
if (linkResolver === void 0) return null;
|
|
808
|
+
throwIfSignalAborted();
|
|
809
|
+
registerPath(parsedPath);
|
|
810
|
+
const candidate = await awaitWithCancellation(linkResolver.resolveLink(parsedPath, createSourceOptions(signal, void 0)));
|
|
811
|
+
throwIfSignalAborted();
|
|
812
|
+
return copyLinkResolution(candidate, parsedPath);
|
|
813
|
+
}
|
|
814
|
+
});
|
|
721
815
|
const reader = Object.freeze({
|
|
722
816
|
getEntry,
|
|
723
817
|
iterateEntries,
|
|
@@ -734,20 +828,7 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
734
828
|
if (!Number.isSafeInteger(bytes) || bytes < 0 || bytes > retainedBytes) throw new TypeError("The retained-memory release is invalid.");
|
|
735
829
|
retainedBytes -= bytes;
|
|
736
830
|
},
|
|
737
|
-
readSourceFile:
|
|
738
|
-
throwIfSignalAborted();
|
|
739
|
-
registerPath(path);
|
|
740
|
-
const bytes = await awaitWithCancellation(loadFile(path, void 0, true));
|
|
741
|
-
throwIfSignalAborted();
|
|
742
|
-
let isReleased = false;
|
|
743
|
-
return {
|
|
744
|
-
bytes,
|
|
745
|
-
release: () => {
|
|
746
|
-
if (!isReleased) retainedBytes -= bytes.byteLength;
|
|
747
|
-
isReleased = true;
|
|
748
|
-
}
|
|
749
|
-
};
|
|
750
|
-
}
|
|
831
|
+
readSourceFile: (path) => readRetainedSource(path, repositoryPages)
|
|
751
832
|
});
|
|
752
833
|
return Object.freeze({
|
|
753
834
|
getResourceUsage: () => Object.freeze({
|
|
@@ -756,6 +837,7 @@ var createRepositoryInspectionSession = (repository, limits, signal) => {
|
|
|
756
837
|
retainedBytes,
|
|
757
838
|
totalBytesRead
|
|
758
839
|
}),
|
|
840
|
+
instructions: instructionView,
|
|
759
841
|
reader,
|
|
760
842
|
throwIfAborted: throwIfSignalAborted
|
|
761
843
|
});
|
|
@@ -1825,8 +1907,8 @@ var validateManifestRelationships = (manifestPath, manifest, discovery, decision
|
|
|
1825
1907
|
const agent = manifest.agents?.[agentId];
|
|
1826
1908
|
if (agent === void 0) continue;
|
|
1827
1909
|
const escapedAgentId = escapeJsonPointerSegment(agentId);
|
|
1828
|
-
for (const referencedPath of
|
|
1829
|
-
for (const referencedPath of
|
|
1910
|
+
for (const [index, referencedPath] of (agent.context ?? []).entries()) validateContextRelationship(referencedPath, `/agents/${escapedAgentId}/context/${index}`, validationContext.validAgentContextPaths, validationContext, agentId);
|
|
1911
|
+
for (const [index, referencedPath] of (agent.decisions ?? []).entries()) validateDecisionRelationship(referencedPath, `/agents/${escapedAgentId}/decisions/${index}`, validationContext, agentId);
|
|
1830
1912
|
}
|
|
1831
1913
|
return collector.finalize();
|
|
1832
1914
|
};
|
|
@@ -1879,11 +1961,34 @@ var parseIntegrationBlock = (text) => {
|
|
|
1879
1961
|
skillPath
|
|
1880
1962
|
};
|
|
1881
1963
|
};
|
|
1964
|
+
var ROOT_AGENTS_IMPORTS = /* @__PURE__ */ new Set(["@AGENTS.md", "@./AGENTS.md"]);
|
|
1965
|
+
var NESTED_AGENTS_IMPORTS = /* @__PURE__ */ new Set(["@../AGENTS.md"]);
|
|
1966
|
+
/**
|
|
1967
|
+
* Reports whether Claude Code instruction text imports the root AGENTS.md on a line of its own.
|
|
1968
|
+
* Lines inside fenced code blocks and imports embedded in other text do not count.
|
|
1969
|
+
* @param text The decoded instruction text.
|
|
1970
|
+
* @param isNested Whether the text belongs to `/.claude/CLAUDE.md` rather than a root file.
|
|
1971
|
+
* @returns `true` when one unfenced line, trimmed of spaces and tabs, is an AGENTS.md import.
|
|
1972
|
+
*/
|
|
1973
|
+
var hasAgentsImport = (text, isNested) => {
|
|
1974
|
+
const imports = isNested ? NESTED_AGENTS_IMPORTS : ROOT_AGENTS_IMPORTS;
|
|
1975
|
+
let fence = null;
|
|
1976
|
+
for (const rawLine of text.replace(/^\uFEFF/u, "").split(/\r\n|\n|\r/u)) {
|
|
1977
|
+
const line = rawLine.replace(/^[ \t]+|[ \t]+$/gu, "");
|
|
1978
|
+
const marker = /^(`{3,}|~{3,})/u.exec(line)?.[1];
|
|
1979
|
+
if (fence !== null) {
|
|
1980
|
+
if (marker !== void 0 && marker[0] === fence[0] && marker.length >= fence.length) fence = null;
|
|
1981
|
+
} else if (marker !== void 0) fence = marker;
|
|
1982
|
+
else if (imports.has(line)) return true;
|
|
1983
|
+
}
|
|
1984
|
+
return false;
|
|
1985
|
+
};
|
|
1882
1986
|
//#endregion
|
|
1883
|
-
//#region src/integration-validation/
|
|
1884
|
-
var AGENTS_PATH = parseRepositoryPath("/AGENTS.md");
|
|
1987
|
+
//#region src/integration-validation/utilities.ts
|
|
1885
1988
|
/**
|
|
1886
1989
|
* Reads bounded untrusted text with a reservation for decoding and temporary string copies.
|
|
1990
|
+
* @param ledger The session ledger that owns the reservation.
|
|
1991
|
+
* @param load Loads the complete bounded source buffer.
|
|
1887
1992
|
* @returns Decoded text or null for invalid UTF-8, with its reservation-release operation.
|
|
1888
1993
|
* @throws
|
|
1889
1994
|
* - ENTRY_NOT_FOUND: The requested repository entry was not found.
|
|
@@ -1897,8 +2002,8 @@ var AGENTS_PATH = parseRepositoryPath("/AGENTS.md");
|
|
|
1897
2002
|
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
1898
2003
|
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
1899
2004
|
*/
|
|
1900
|
-
var
|
|
1901
|
-
const source = await
|
|
2005
|
+
var readRetainedText = async (ledger, load) => {
|
|
2006
|
+
const source = await load();
|
|
1902
2007
|
const reservation = source.bytes.byteLength * 8;
|
|
1903
2008
|
let isReserved = false;
|
|
1904
2009
|
try {
|
|
@@ -1924,8 +2029,21 @@ var readText = async (ledger, path) => {
|
|
|
1924
2029
|
/** Distinguishes missing and non-regular files without an extra entry lookup or following symlinks. */
|
|
1925
2030
|
var getAbsentKind = (error) => error instanceof RepositorySourceException ? error.code === "ENTRY_NOT_FOUND" ? "missing" : error.code === "ENTRY_NOT_FILE" ? "non-regular" : null : null;
|
|
1926
2031
|
/**
|
|
1927
|
-
*
|
|
1928
|
-
* @
|
|
2032
|
+
* Explains why a linked instruction file cannot be read, or returns null for a readable link.
|
|
2033
|
+
* @param resolution The resolver's classification, or null when no resolver is available.
|
|
2034
|
+
* @returns The content-free link state, or null when the final target is a regular file.
|
|
2035
|
+
*/
|
|
2036
|
+
var getUnreadableLinkState = (resolution) => {
|
|
2037
|
+
if (resolution === null) return "unavailable";
|
|
2038
|
+
if (resolution.state === "inside" || resolution.state === "outside") return resolution.targetType === "file" ? null : resolution.targetType;
|
|
2039
|
+
return resolution.state;
|
|
2040
|
+
};
|
|
2041
|
+
//#endregion
|
|
2042
|
+
//#region src/integration-validation/agents-inspection.ts
|
|
2043
|
+
var AGENTS_PATH$1 = parseRepositoryPath("/AGENTS.md");
|
|
2044
|
+
/**
|
|
2045
|
+
* Checks one readable AGENTS.md text against its referenced skill installation.
|
|
2046
|
+
* @returns A promise that settles after at most one integration warning was recorded.
|
|
1929
2047
|
* @throws
|
|
1930
2048
|
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
1931
2049
|
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
@@ -1936,52 +2054,43 @@ var getAbsentKind = (error) => error instanceof RepositorySourceException ? erro
|
|
|
1936
2054
|
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
1937
2055
|
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
1938
2056
|
*/
|
|
1939
|
-
var
|
|
1940
|
-
const ledger =
|
|
1941
|
-
const collector = createCoreDiagnosticCollector(limits, "validate-project");
|
|
1942
|
-
const report = (code, details) => {
|
|
1943
|
-
collector.add({
|
|
1944
|
-
code,
|
|
1945
|
-
path: AGENTS_PATH,
|
|
1946
|
-
subject: AGENTS_PATH,
|
|
1947
|
-
qualifier: null,
|
|
1948
|
-
entity: { integrationPath: AGENTS_PATH },
|
|
1949
|
-
details
|
|
1950
|
-
});
|
|
1951
|
-
return collector.finalize();
|
|
1952
|
-
};
|
|
2057
|
+
var checkAgentsDocument = async (context, report, load, entryDetails) => {
|
|
2058
|
+
const { ledger, reader, signal } = context;
|
|
1953
2059
|
let document;
|
|
1954
2060
|
try {
|
|
1955
|
-
document = await
|
|
2061
|
+
document = await readRetainedText(ledger, load);
|
|
1956
2062
|
} catch (error) {
|
|
1957
|
-
const
|
|
1958
|
-
if (
|
|
1959
|
-
|
|
2063
|
+
const absentKind = getAbsentKind(error);
|
|
2064
|
+
if (absentKind === null) throw error;
|
|
2065
|
+
return entryDetails["entryKind"] === "symlink" ? report("MOLDEA_INTEGRATION_UNVERIFIED", {
|
|
2066
|
+
entryKind: "symlink",
|
|
2067
|
+
linkState: "not-file"
|
|
2068
|
+
}) : report("MOLDEA_INTEGRATION_BLOCK_MISSING", { entryKind: absentKind });
|
|
1960
2069
|
}
|
|
1961
2070
|
try {
|
|
1962
2071
|
if (document.text === null) return report("MOLDEA_INTEGRATION_BLOCK_MISSING", {
|
|
1963
|
-
|
|
2072
|
+
...entryDetails,
|
|
1964
2073
|
reason: "invalid-utf8"
|
|
1965
2074
|
});
|
|
1966
2075
|
const parsed = parseIntegrationBlock(document.text);
|
|
1967
2076
|
if (parsed.kind === "missing") return report(parsed.reason.startsWith("block-") ? "MOLDEA_INTEGRATION_BLOCK_MISSING" : "MOLDEA_INTEGRATION_SKILL_MISSING", {
|
|
1968
|
-
|
|
2077
|
+
...entryDetails,
|
|
1969
2078
|
reason: parsed.reason
|
|
1970
2079
|
});
|
|
1971
2080
|
const { skillPath } = parsed;
|
|
1972
2081
|
for (const file of ["SKILL.md", "scripts/relevance-gate.mjs"]) {
|
|
1973
2082
|
const path = parseRepositoryPath(`/${skillPath}/${file}`);
|
|
1974
|
-
const
|
|
1975
|
-
if (
|
|
2083
|
+
const skillEntry = await reader.getEntry(path, signal === void 0 ? void 0 : { signal });
|
|
2084
|
+
if (skillEntry?.type !== "file") return report("MOLDEA_INTEGRATION_SKILL_MISSING", {
|
|
1976
2085
|
referencedPath: `/${skillPath}`,
|
|
1977
2086
|
missingFile: path,
|
|
1978
|
-
entryKind:
|
|
2087
|
+
entryKind: skillEntry?.type ?? "missing"
|
|
1979
2088
|
});
|
|
1980
2089
|
}
|
|
1981
2090
|
const assetPath = parseRepositoryPath(`/${skillPath}/assets/managed-agents-block.md`);
|
|
1982
2091
|
let asset;
|
|
1983
2092
|
try {
|
|
1984
|
-
asset = await
|
|
2093
|
+
asset = await readRetainedText(ledger, () => ledger.readSourceFile(assetPath));
|
|
1985
2094
|
} catch (error) {
|
|
1986
2095
|
const entryKind = getAbsentKind(error);
|
|
1987
2096
|
if (entryKind !== null) return report("MOLDEA_INTEGRATION_SKILL_MISSING", {
|
|
@@ -2011,7 +2120,6 @@ var inspectCodingAgentIntegration = async (reader, limits, signal) => {
|
|
|
2011
2120
|
} finally {
|
|
2012
2121
|
ledger.release(renderedReservation);
|
|
2013
2122
|
}
|
|
2014
|
-
return collector.finalize();
|
|
2015
2123
|
} finally {
|
|
2016
2124
|
asset.release();
|
|
2017
2125
|
}
|
|
@@ -2019,6 +2127,210 @@ var inspectCodingAgentIntegration = async (reader, limits, signal) => {
|
|
|
2019
2127
|
document.release();
|
|
2020
2128
|
}
|
|
2021
2129
|
};
|
|
2130
|
+
/**
|
|
2131
|
+
* Checks root AGENTS.md against its referenced skill installation. A symlinked AGENTS.md whose
|
|
2132
|
+
* final target is a readable regular file, inside or outside the repository, is checked on the
|
|
2133
|
+
* target text; any other link is reported as unverifiable without reading it.
|
|
2134
|
+
* @param context The instruction view, repository reader, ledger, and warning recorder.
|
|
2135
|
+
* @returns What AGENTS.md is, including its link resolution, for the Claude Code check.
|
|
2136
|
+
* @throws
|
|
2137
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
2138
|
+
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
2139
|
+
* - ABORTED: The Core operation was aborted.
|
|
2140
|
+
* - ABORTED: The repository operation was aborted.
|
|
2141
|
+
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
2142
|
+
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
2143
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
2144
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
2145
|
+
*/
|
|
2146
|
+
var inspectAgentsIntegration = async (context) => {
|
|
2147
|
+
const { instructions } = context;
|
|
2148
|
+
const report = (code, details) => context.report(code, AGENTS_PATH$1, details);
|
|
2149
|
+
const entry = await instructions.getEntry(AGENTS_PATH$1);
|
|
2150
|
+
if (entry === null) {
|
|
2151
|
+
report("MOLDEA_INTEGRATION_BLOCK_MISSING", { entryKind: "missing" });
|
|
2152
|
+
return { kind: "missing" };
|
|
2153
|
+
}
|
|
2154
|
+
if (entry.type === "directory") {
|
|
2155
|
+
report("MOLDEA_INTEGRATION_BLOCK_MISSING", { entryKind: "directory" });
|
|
2156
|
+
return { kind: "directory" };
|
|
2157
|
+
}
|
|
2158
|
+
if (entry.type === "file") {
|
|
2159
|
+
await checkAgentsDocument(context, report, () => instructions.readSourceFile(AGENTS_PATH$1), { entryKind: "file" });
|
|
2160
|
+
return { kind: "file" };
|
|
2161
|
+
}
|
|
2162
|
+
const resolution = await instructions.resolveLink(AGENTS_PATH$1);
|
|
2163
|
+
const linkState = getUnreadableLinkState(resolution);
|
|
2164
|
+
if (linkState !== null || resolution === null) report("MOLDEA_INTEGRATION_UNVERIFIED", {
|
|
2165
|
+
entryKind: "symlink",
|
|
2166
|
+
linkState: linkState ?? "unavailable"
|
|
2167
|
+
});
|
|
2168
|
+
else await checkAgentsDocument(context, report, () => instructions.readLinkedSourceFile(AGENTS_PATH$1), {
|
|
2169
|
+
entryKind: "symlink",
|
|
2170
|
+
linkTarget: resolution.state
|
|
2171
|
+
});
|
|
2172
|
+
return {
|
|
2173
|
+
kind: "link",
|
|
2174
|
+
resolution
|
|
2175
|
+
};
|
|
2176
|
+
};
|
|
2177
|
+
//#endregion
|
|
2178
|
+
//#region src/integration-validation/claude-inspection.ts
|
|
2179
|
+
var AGENTS_PATH = parseRepositoryPath("/AGENTS.md");
|
|
2180
|
+
var CLAUDE_PATH = parseRepositoryPath("/CLAUDE.md");
|
|
2181
|
+
var NESTED_CLAUDE_PATH = parseRepositoryPath("/.claude/CLAUDE.md");
|
|
2182
|
+
var LOCAL_CLAUDE_PATH = parseRepositoryPath("/CLAUDE.local.md");
|
|
2183
|
+
/** Recognizes a link between a Claude file and AGENTS.md without reading either file. */
|
|
2184
|
+
var isLinkedToAgents = (path, resolution, agents) => {
|
|
2185
|
+
const agentsResolution = agents.kind === "link" ? agents.resolution : null;
|
|
2186
|
+
if (agentsResolution?.state === "inside" && agentsResolution.targetPath === path) return true;
|
|
2187
|
+
if (resolution === null || resolution.state !== "inside" && resolution.state !== "outside") return false;
|
|
2188
|
+
if (agents.kind === "file") return resolution.state === "inside" && resolution.targetPath === AGENTS_PATH;
|
|
2189
|
+
return (agentsResolution?.state === "inside" || agentsResolution?.state === "outside") && agentsResolution.targetIdentity === resolution.targetIdentity;
|
|
2190
|
+
};
|
|
2191
|
+
/**
|
|
2192
|
+
* Determines whether one Claude Code file loads AGENTS.md through an import line, a link to the
|
|
2193
|
+
* same final target, or AGENTS.md linking to it. A linked Claude file with a regular-file target
|
|
2194
|
+
* is checked for an import line as if the file were at the link's own location.
|
|
2195
|
+
* @returns The assessment, reading at most the file or its link target once.
|
|
2196
|
+
* @throws
|
|
2197
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
2198
|
+
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
2199
|
+
* - ABORTED: The Core operation was aborted.
|
|
2200
|
+
* - ABORTED: The repository operation was aborted.
|
|
2201
|
+
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
2202
|
+
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
2203
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
2204
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
2205
|
+
*/
|
|
2206
|
+
var assessClaudeFile = async (context, path, agents) => {
|
|
2207
|
+
const { instructions, ledger } = context;
|
|
2208
|
+
const entry = await instructions.getEntry(path);
|
|
2209
|
+
if (entry === null) return { kind: "absent" };
|
|
2210
|
+
if (isLinkedToAgents(path, null, agents)) return { kind: "loads" };
|
|
2211
|
+
if (entry.type === "directory") return {
|
|
2212
|
+
entryKind: "directory",
|
|
2213
|
+
kind: "not-loading"
|
|
2214
|
+
};
|
|
2215
|
+
let load = () => instructions.readSourceFile(path);
|
|
2216
|
+
if (entry.type === "symlink") {
|
|
2217
|
+
const resolution = await instructions.resolveLink(path);
|
|
2218
|
+
if (isLinkedToAgents(path, resolution, agents)) return { kind: "loads" };
|
|
2219
|
+
const linkState = getUnreadableLinkState(resolution);
|
|
2220
|
+
if (linkState !== null) return {
|
|
2221
|
+
kind: "unverified",
|
|
2222
|
+
linkState
|
|
2223
|
+
};
|
|
2224
|
+
load = () => instructions.readLinkedSourceFile(path);
|
|
2225
|
+
}
|
|
2226
|
+
let document;
|
|
2227
|
+
try {
|
|
2228
|
+
document = await readRetainedText(ledger, load);
|
|
2229
|
+
} catch (error) {
|
|
2230
|
+
if (getAbsentKind(error) === null) throw error;
|
|
2231
|
+
return entry.type === "symlink" ? {
|
|
2232
|
+
kind: "unverified",
|
|
2233
|
+
linkState: "not-file"
|
|
2234
|
+
} : { kind: "absent" };
|
|
2235
|
+
}
|
|
2236
|
+
try {
|
|
2237
|
+
return document.text !== null && hasAgentsImport(document.text, path === NESTED_CLAUDE_PATH) ? { kind: "loads" } : {
|
|
2238
|
+
entryKind: entry.type,
|
|
2239
|
+
kind: "not-loading"
|
|
2240
|
+
};
|
|
2241
|
+
} finally {
|
|
2242
|
+
document.release();
|
|
2243
|
+
}
|
|
2244
|
+
};
|
|
2245
|
+
/**
|
|
2246
|
+
* Checks whether Claude Code loads AGENTS.md. When `/CLAUDE.md` or `/.claude/CLAUDE.md` exists,
|
|
2247
|
+
* only those shared files count; `/CLAUDE.local.md` counts only when neither exists. At most one
|
|
2248
|
+
* Claude warning is recorded: unverifiable for the first unverifiable counted file when none
|
|
2249
|
+
* loads AGENTS.md, otherwise a missing import for the governing file.
|
|
2250
|
+
* @param context The instruction view, ledger, and warning recorder.
|
|
2251
|
+
* @param agents What root AGENTS.md is, as the AGENTS.md check observed it.
|
|
2252
|
+
* @returns A promise that settles after at most one Claude warning was recorded.
|
|
2253
|
+
* @throws
|
|
2254
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
2255
|
+
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
2256
|
+
* - ABORTED: The Core operation was aborted.
|
|
2257
|
+
* - ABORTED: The repository operation was aborted.
|
|
2258
|
+
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
2259
|
+
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
2260
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
2261
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
2262
|
+
*/
|
|
2263
|
+
var inspectClaudeIntegration = async (context, agents) => {
|
|
2264
|
+
const counted = [];
|
|
2265
|
+
for (const path of [CLAUDE_PATH, NESTED_CLAUDE_PATH]) {
|
|
2266
|
+
const assessment = await assessClaudeFile(context, path, agents);
|
|
2267
|
+
if (assessment.kind === "loads") return;
|
|
2268
|
+
if (assessment.kind !== "absent") counted.push({
|
|
2269
|
+
assessment,
|
|
2270
|
+
path
|
|
2271
|
+
});
|
|
2272
|
+
}
|
|
2273
|
+
if (counted.length === 0) {
|
|
2274
|
+
const assessment = await assessClaudeFile(context, LOCAL_CLAUDE_PATH, agents);
|
|
2275
|
+
if (assessment.kind === "absent" || assessment.kind === "loads") return;
|
|
2276
|
+
counted.push({
|
|
2277
|
+
assessment,
|
|
2278
|
+
path: LOCAL_CLAUDE_PATH
|
|
2279
|
+
});
|
|
2280
|
+
}
|
|
2281
|
+
const unverifiable = counted.find(({ assessment }) => assessment.kind === "unverified");
|
|
2282
|
+
if (unverifiable?.assessment.kind === "unverified") {
|
|
2283
|
+
context.report("MOLDEA_INTEGRATION_UNVERIFIED", unverifiable.path, {
|
|
2284
|
+
entryKind: "symlink",
|
|
2285
|
+
linkState: unverifiable.assessment.linkState
|
|
2286
|
+
});
|
|
2287
|
+
return;
|
|
2288
|
+
}
|
|
2289
|
+
const governing = counted[0];
|
|
2290
|
+
if (governing?.assessment.kind === "not-loading") context.report("MOLDEA_INTEGRATION_CLAUDE_IMPORT_MISSING", governing.path, { entryKind: governing.assessment.entryKind });
|
|
2291
|
+
};
|
|
2292
|
+
//#endregion
|
|
2293
|
+
//#region src/integration-validation/inspection.ts
|
|
2294
|
+
/**
|
|
2295
|
+
* Checks the coding-agent integration: root AGENTS.md and the Claude Code instruction files
|
|
2296
|
+
* through the instruction view, and the referenced skill installation through the repository
|
|
2297
|
+
* reader, with at most six entry lookups, four link resolutions, and five bounded reads.
|
|
2298
|
+
* @param reader The repository inspection reader for skill files and the managed asset.
|
|
2299
|
+
* @param instructions The instruction view for the coding-agent instruction paths.
|
|
2300
|
+
* @param limits The immutable resource limits for the inspection.
|
|
2301
|
+
* @param signal Optional cancellation for repository lookups.
|
|
2302
|
+
* @returns Completed content-free integration warnings, never an execution or runtime-wiring claim.
|
|
2303
|
+
* @throws
|
|
2304
|
+
* - RESOURCE_LIMIT_EXCEEDED: A Core resource limit was exceeded.
|
|
2305
|
+
* - RESOURCE_LIMIT_EXCEEDED: A named repository resource limit was exceeded.
|
|
2306
|
+
* - ABORTED: The Core operation was aborted.
|
|
2307
|
+
* - ABORTED: The repository operation was aborted.
|
|
2308
|
+
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
2309
|
+
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
2310
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
2311
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
2312
|
+
*/
|
|
2313
|
+
var inspectCodingAgentIntegration = async (reader, instructions, limits, signal) => {
|
|
2314
|
+
const collector = createCoreDiagnosticCollector(limits, "validate-project");
|
|
2315
|
+
const context = {
|
|
2316
|
+
instructions,
|
|
2317
|
+
ledger: getRetainedMemory(reader),
|
|
2318
|
+
reader,
|
|
2319
|
+
report: (code, subject, details) => {
|
|
2320
|
+
collector.add({
|
|
2321
|
+
code,
|
|
2322
|
+
path: subject,
|
|
2323
|
+
subject,
|
|
2324
|
+
qualifier: null,
|
|
2325
|
+
entity: { integrationPath: subject },
|
|
2326
|
+
details
|
|
2327
|
+
});
|
|
2328
|
+
},
|
|
2329
|
+
...signal === void 0 ? {} : { signal }
|
|
2330
|
+
};
|
|
2331
|
+
await inspectClaudeIntegration(context, await inspectAgentsIntegration(context));
|
|
2332
|
+
return collector.finalize();
|
|
2333
|
+
};
|
|
2022
2334
|
//#endregion
|
|
2023
2335
|
//#region src/impact-pattern-validation/inspection.ts
|
|
2024
2336
|
/** Identifies the canonical document owning an impact relationship. */
|
|
@@ -2245,7 +2557,7 @@ var inspectMirrors = async (repository, manifestPath, agents, options, signal) =
|
|
|
2245
2557
|
for (const agent of [...agents].sort((left, right) => compareExactStrings(left.id, right.id))) {
|
|
2246
2558
|
const mirrors = [];
|
|
2247
2559
|
if (agent.instruction !== null) {
|
|
2248
|
-
const declaredMirrors =
|
|
2560
|
+
const declaredMirrors = agent.declaration.mirrors ?? [];
|
|
2249
2561
|
for (const [index, mirrorPath] of declaredMirrors.entries()) {
|
|
2250
2562
|
const mirror = await inspectMirror(repository, manifestPath, agent.instruction, mirrorPath, `/agents/${escapeJsonPointerSegment(agent.id)}/mirrors/${index}`, agent.id, options, collector, operationOptions, signal);
|
|
2251
2563
|
if (mirror !== null) mirrors.push(mirror);
|
|
@@ -2899,7 +3211,7 @@ var inspectUniversalProject = async (context, options) => {
|
|
|
2899
3211
|
addDiagnostics(collector, mirrorInspection.diagnostics);
|
|
2900
3212
|
}
|
|
2901
3213
|
session.throwIfAborted();
|
|
2902
|
-
addDiagnostics(collector, await inspectCodingAgentIntegration(session.reader, options.limits, signal));
|
|
3214
|
+
addDiagnostics(collector, await inspectCodingAgentIntegration(session.reader, session.instructions, options.limits, signal));
|
|
2903
3215
|
const patterns = indexedManifest === null ? {
|
|
2904
3216
|
completed: false,
|
|
2905
3217
|
diagnostics: []
|
|
@@ -2909,7 +3221,9 @@ var inspectUniversalProject = async (context, options) => {
|
|
|
2909
3221
|
const diagnostics = applyWarningAcceptances(collector.finalize(), indexedManifest?.value.acceptedWarnings ?? [], /* @__PURE__ */ new Set([...[
|
|
2910
3222
|
"MOLDEA_INTEGRATION_BLOCK_MISSING",
|
|
2911
3223
|
"MOLDEA_INTEGRATION_SKILL_MISSING",
|
|
2912
|
-
"MOLDEA_INTEGRATION_BLOCK_STALE"
|
|
3224
|
+
"MOLDEA_INTEGRATION_BLOCK_STALE",
|
|
3225
|
+
"MOLDEA_INTEGRATION_UNVERIFIED",
|
|
3226
|
+
"MOLDEA_INTEGRATION_CLAUDE_IMPORT_MISSING"
|
|
2913
3227
|
], ...patterns.completed ? ["MOLDEA_IMPACT_PATTERN_UNMATCHED"] : []]), options.limits);
|
|
2914
3228
|
const project = !diagnostics.some((diagnostic) => diagnostic.severity === "error") && indexedManifest !== null && projectAssets.project !== null ? createProjectIndex({
|
|
2915
3229
|
agentMirrors,
|
|
@@ -2941,6 +3255,21 @@ var invalidArgument$1 = () => {
|
|
|
2941
3255
|
var isRepositoryReader = (candidate) => {
|
|
2942
3256
|
return isRecord(candidate) && isRecord(candidate["snapshot"]) && typeof candidate["snapshot"]["id"] === "string" && typeof candidate["snapshot"]["sourceKind"] === "string" && typeof candidate["compare"] === "function" && typeof candidate["getEntry"] === "function" && typeof candidate["listEntriesPage"] === "function" && typeof candidate["readFilePage"] === "function";
|
|
2943
3257
|
};
|
|
3258
|
+
var isLinkResolver = (candidate) => {
|
|
3259
|
+
return isRecord(candidate) && isRecord(candidate["snapshot"]) && typeof candidate["snapshot"]["id"] === "string" && typeof candidate["snapshot"]["sourceKind"] === "string" && typeof candidate["resolveLink"] === "function" && typeof candidate["readLinkTargetPage"] === "function";
|
|
3260
|
+
};
|
|
3261
|
+
var validateInstructions = (candidate) => {
|
|
3262
|
+
if (!isRecord(candidate) || Reflect.ownKeys(candidate).some((key) => key !== "reader" && key !== "linkResolver")) return invalidArgument$1();
|
|
3263
|
+
const reader = candidate["reader"];
|
|
3264
|
+
const linkResolver = candidate["linkResolver"];
|
|
3265
|
+
if (!isRepositoryReader(reader)) return invalidArgument$1();
|
|
3266
|
+
if (linkResolver === void 0) return { reader };
|
|
3267
|
+
if (!isLinkResolver(linkResolver) || linkResolver.snapshot.id !== reader.snapshot.id) return invalidArgument$1();
|
|
3268
|
+
return {
|
|
3269
|
+
linkResolver,
|
|
3270
|
+
reader
|
|
3271
|
+
};
|
|
3272
|
+
};
|
|
2944
3273
|
var isAbortSignal = (candidate) => {
|
|
2945
3274
|
return isRecord(candidate) && typeof candidate["aborted"] === "boolean" && typeof candidate["addEventListener"] === "function" && typeof candidate["removeEventListener"] === "function";
|
|
2946
3275
|
};
|
|
@@ -2948,9 +3277,11 @@ var validateInput = (candidate) => {
|
|
|
2948
3277
|
try {
|
|
2949
3278
|
if (!isRecord(candidate)) return invalidArgument$1();
|
|
2950
3279
|
const repository = candidate["repository"];
|
|
3280
|
+
const instructions = candidate["instructions"];
|
|
2951
3281
|
const signal = candidate["signal"];
|
|
2952
|
-
if (Reflect.ownKeys(candidate).some((key) => key !== "repository" && key !== "signal") || !isRepositoryReader(repository) || signal !== void 0 && !isAbortSignal(signal)) return invalidArgument$1();
|
|
3282
|
+
if (Reflect.ownKeys(candidate).some((key) => key !== "repository" && key !== "instructions" && key !== "signal") || !isRepositoryReader(repository) || signal !== void 0 && !isAbortSignal(signal)) return invalidArgument$1();
|
|
2953
3283
|
return {
|
|
3284
|
+
...instructions === void 0 ? {} : { instructions: validateInstructions(instructions) },
|
|
2954
3285
|
repository,
|
|
2955
3286
|
...signal === void 0 ? {} : { signal }
|
|
2956
3287
|
};
|
|
@@ -2961,7 +3292,7 @@ var validateInput = (candidate) => {
|
|
|
2961
3292
|
};
|
|
2962
3293
|
/**
|
|
2963
3294
|
* Inspects one coherent repository snapshot through universal file and export validation.
|
|
2964
|
-
* @param input The untrusted source-neutral reader
|
|
3295
|
+
* @param input The untrusted source-neutral reader, optional instruction source, and signal.
|
|
2965
3296
|
* @param options The immutable Core configuration snapshot.
|
|
2966
3297
|
* @returns A promise resolving to the frozen all-or-nothing project inspection result.
|
|
2967
3298
|
* @throws
|
|
@@ -2983,7 +3314,7 @@ var validateInput = (candidate) => {
|
|
|
2983
3314
|
var validateProjectState = async (input, options) => {
|
|
2984
3315
|
const validatedInput = validateInput(input);
|
|
2985
3316
|
const operationOptions = createCoreOperationOptionsSnapshot(options);
|
|
2986
|
-
const session = createRepositoryInspectionSession(validatedInput.repository, operationOptions.limits, validatedInput.signal);
|
|
3317
|
+
const session = createRepositoryInspectionSession(validatedInput.repository, operationOptions.limits, validatedInput.signal, validatedInput.instructions);
|
|
2987
3318
|
const universal = await inspectUniversalProject({
|
|
2988
3319
|
session,
|
|
2989
3320
|
...validatedInput.signal === void 0 ? {} : { signal: validatedInput.signal }
|
|
@@ -3363,4 +3694,4 @@ var createCore = (options) => {
|
|
|
3363
3694
|
//#endregion
|
|
3364
3695
|
export { createCore as n, parseIntegrationBlock as r, core_exports as t };
|
|
3365
3696
|
|
|
3366
|
-
//# sourceMappingURL=core-
|
|
3697
|
+
//# sourceMappingURL=core-CMuQrqRI.js.map
|