rea-agents 2.4.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -19
- package/bridge/ghidra/ReaGhidraBridge.java +524 -4
- package/bridge/hopper_bridge.py +313 -28
- package/dist/application/AnalysisClientCleanup.js +14 -0
- package/dist/application/AnalysisContextQueries.js +130 -0
- package/dist/application/AnalysisSnapshotCache.js +4 -2
- package/dist/application/ApplicationWorkflowEvidenceResolver.js +31 -13
- package/dist/application/ArtifactInventory/scanCanonical.js +1 -1
- package/dist/application/BinarySession.js +20 -8
- package/dist/application/BinarySessionComposition.js +21 -0
- package/dist/application/BinarySessionRecords.js +79 -9
- package/dist/application/BinarySessionStatus.js +31 -1
- package/dist/application/BrowserEvidence.js +14 -0
- package/dist/application/BrowserScenarioCapturePort.js +1 -0
- package/dist/application/BrowserScenarioCaptureService.js +53 -0
- package/dist/application/BrowserScenarioEvidence.js +40 -0
- package/dist/application/CallPathTracing.js +160 -0
- package/dist/application/CapabilityInventory.js +84 -14
- package/dist/application/ClientRegistrationStatus.js +4 -1
- package/dist/application/CompositeProvider.js +10 -1
- package/dist/application/DirectAnalysis.js +13 -4
- package/dist/application/EnhancedLiteralTracing.js +118 -0
- package/dist/application/EnhancedTools.js +71 -127
- package/dist/application/EvidenceLedger.js +45 -16
- package/dist/application/JavaScriptApplicationWorkflowEvidence.js +13 -0
- package/dist/application/JavaScriptApplicationWorkflowService.js +27 -1
- package/dist/application/JavaScriptArtifactAnalysis.js +13 -4
- package/dist/application/JavaScriptRuntimeObservationEvidence.js +34 -0
- package/dist/application/JavaScriptRuntimeObservationPort.js +1 -0
- package/dist/application/JavaScriptRuntimeObservationService.js +46 -0
- package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +147 -0
- package/dist/application/JavaScriptSemanticGraphBuilder.js +34 -6
- package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +156 -0
- package/dist/application/JavaScriptSemanticGraphConstruction.js +2 -2
- package/dist/application/JavaScriptSemanticGraphDataProjection.js +203 -0
- package/dist/application/JavaScriptSemanticGraphFingerprintProjection.js +25 -0
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +129 -8
- package/dist/application/JavaScriptSemanticGraphObjectProjection.js +81 -0
- package/dist/application/JavaScriptSemanticGraphProjection.js +14 -7
- package/dist/application/JavaScriptSemanticGraphResourceProjection.js +59 -0
- package/dist/application/JavaScriptSemanticGraphValueProjection.js +77 -0
- package/dist/application/LazyAnalysisProvider.js +77 -0
- package/dist/application/LoopbackReplay.js +1 -1
- package/dist/application/NativeApiInspection.js +80 -0
- package/dist/application/ProcessReactiveEffects.js +6 -0
- package/dist/application/ProcessReactiveHarness.js +16 -1
- package/dist/application/ProjectPermissionStore.js +1 -0
- package/dist/application/ReconstructionObligationAuthority.js +72 -0
- package/dist/application/ReconstructionObligationCandidates.js +265 -0
- package/dist/application/ReconstructionObligationLedgerDiagnostics.js +47 -0
- package/dist/application/ReconstructionObligationLedgerEvaluation.js +263 -0
- package/dist/application/ReconstructionObligationLedgerProjection.js +86 -0
- package/dist/application/ReconstructionObligationLedgerService.js +72 -0
- package/dist/application/ReconstructionObligationOriginalCases.js +33 -0
- package/dist/application/ReconstructionObligationPolicies.js +132 -0
- package/dist/application/ReconstructionReadinessService.js +48 -0
- package/dist/application/SessionProviderRouter.js +6 -6
- package/dist/application/SetupClientConfiguration.js +4 -2
- package/dist/application/runtime.js +26 -9
- package/dist/artifacts/ArtifactProvider.js +87 -22
- package/dist/browser/BrowserScenarioSecrets.js +53 -0
- package/dist/browser/BrowserScenarioSessionPort.js +1 -0
- package/dist/browser/CdpBrowserProvider.js +2 -2
- package/dist/browser/CdpCaptureDocuments.js +57 -0
- package/dist/browser/CdpCaptureStorage.js +71 -29
- package/dist/browser/CdpCaptureStorageFingerprints.js +328 -0
- package/dist/browser/CdpEndpoint.js +8 -6
- package/dist/browser/CdpPageCapture.js +2 -0
- package/dist/browser/JavaScriptRuntimeScope.js +38 -0
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +259 -0
- package/dist/browser/PlaywrightExecutionBoundary.js +42 -0
- package/dist/browser/PlaywrightScenarioActions.js +62 -0
- package/dist/browser/PlaywrightScenarioArtifacts.js +238 -0
- package/dist/browser/PlaywrightScenarioBrowser.js +144 -0
- package/dist/browser/PlaywrightScenarioEvents.js +301 -0
- package/dist/browser/PlaywrightScenarioSession.js +300 -0
- package/dist/browser/V8InspectorCaptureProjection.js +110 -0
- package/dist/browser/V8InspectorEndpoint.js +72 -0
- package/dist/browser/V8InspectorProvider.js +267 -0
- package/dist/catalogIdentity.js +11 -3
- package/dist/cli/artifactCommands.js +44 -3
- package/dist/cli/coreAnalysisCommands.js +78 -0
- package/dist/cli.js +4 -0
- package/dist/cliApplicationCommands.js +30 -2
- package/dist/cliBrowserAdvancedCommands.js +17 -5
- package/dist/cliBrowserCommands.js +1 -0
- package/dist/cliBrowserScenarioCommands.js +43 -0
- package/dist/cliCommandNames.js +9 -0
- package/dist/cliJavaScriptRuntimeCommands.js +164 -0
- package/dist/cliObservationOptions.js +4 -0
- package/dist/cliPolicyCommands.js +1 -0
- package/dist/config/environment.js +12 -0
- package/dist/config/parseConfig.js +88 -17
- package/dist/contracts/analysisSearchContract.js +14 -0
- package/dist/contracts/applicationToolContracts.js +86 -2
- package/dist/contracts/applicationWorkflowInputContracts.js +18 -0
- package/dist/contracts/artifactToolContracts.js +29 -2
- package/dist/contracts/browserProviderToolContracts.js +7 -0
- package/dist/contracts/browserScenarioToolContracts.js +81 -0
- package/dist/contracts/browserToolContracts.js +88 -98
- package/dist/contracts/enhancedInputs.js +35 -6
- package/dist/contracts/functionInstructionContract.js +8 -0
- package/dist/contracts/functionWorkflowToolContracts.js +30 -0
- package/dist/contracts/hopperMemoryContracts.js +22 -0
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +42 -0
- package/dist/contracts/javascriptRuntimeObservationToolContracts.js +58 -0
- package/dist/contracts/promptContracts.js +14 -15
- package/dist/contracts/reconstructionReadinessExample.js +436 -0
- package/dist/contracts/toolContractExamples.js +8 -0
- package/dist/contracts/toolContractTypes.js +1 -0
- package/dist/contracts/toolContracts.js +34 -25
- package/dist/contracts/toolEffects.js +25 -0
- package/dist/contracts/toolOutputSchemaGroups.js +120 -30
- package/dist/contracts/toolOutputSchemaPrimitives.js +37 -0
- package/dist/domain/analysisErrorPresentation.js +8 -2
- package/dist/domain/analysisErrorProjection.js +9 -0
- package/dist/domain/artifactInspection.js +347 -0
- package/dist/domain/browserCaptureComparison.js +82 -0
- package/dist/domain/browserObservation.js +8 -1
- package/dist/domain/browserObservationErrors.js +1 -0
- package/dist/domain/browserObservationSchemas.js +26 -0
- package/dist/domain/browserScenario.js +165 -0
- package/dist/domain/browserScenarioCapture.js +57 -0
- package/dist/domain/browserScenarioCaptureValues.js +204 -0
- package/dist/domain/browserScenarioDiff.js +324 -0
- package/dist/domain/browserScenarioDiffValues.js +157 -0
- package/dist/domain/browserScenarioNormalization.js +45 -0
- package/dist/domain/browserScenarioValues.js +372 -0
- package/dist/domain/bytecodeProvider.js +179 -0
- package/dist/domain/conformancePackage.js +169 -0
- package/dist/domain/conformanceReplay.js +104 -0
- package/dist/domain/conformanceTrustGate.js +193 -0
- package/dist/domain/customProtocolCapture.js +137 -0
- package/dist/domain/eventProcessTree.js +214 -0
- package/dist/domain/evidenceBundle.js +47 -0
- package/dist/domain/hopperStartupFailure.js +1 -1
- package/dist/domain/hopperValues.js +14 -1
- package/dist/domain/inputIssueProjection.js +7 -1
- package/dist/domain/javascriptRuntimeObservation.js +170 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +120 -2
- package/dist/domain/javascriptRuntimeReconciliationResult.js +3 -3
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +2 -2
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
- package/dist/domain/javascriptSemanticAnalysis.js +13 -16
- package/dist/domain/javascriptSemanticAsyncEffects.js +253 -0
- package/dist/domain/javascriptSemanticChildProcesses.js +237 -0
- package/dist/domain/javascriptSemanticDataEffectHelpers.js +125 -0
- package/dist/domain/javascriptSemanticDataEffects.js +284 -0
- package/dist/domain/javascriptSemanticDerivedAnalysis.js +41 -0
- package/dist/domain/javascriptSemanticFingerprints.js +174 -0
- package/dist/domain/javascriptSemanticIr.js +21 -1
- package/dist/domain/javascriptSemanticObjects.js +115 -0
- package/dist/domain/javascriptSemanticPromises.js +290 -0
- package/dist/domain/javascriptSemanticResources.js +136 -0
- package/dist/domain/javascriptSourceParser.js +15 -0
- package/dist/domain/javascriptStaticAnalysis.js +12 -15
- package/dist/domain/javascriptStaticAnalysisBundler.js +38 -0
- package/dist/domain/javascriptStaticAnalysisCalls.js +23 -1
- package/dist/domain/javascriptStaticAnalysisHelpers.js +8 -0
- package/dist/domain/mobileApplicationInvestigation.js +159 -0
- package/dist/domain/nativeApiBoundary.js +130 -0
- package/dist/domain/objcSwiftMetadata.js +150 -0
- package/dist/domain/packageAnalysis.js +123 -0
- package/dist/domain/peInspection.js +196 -0
- package/dist/domain/processCapture.js +8 -2
- package/dist/domain/processReactiveScenario.js +1 -0
- package/dist/domain/processReactiveTransition.js +9 -4
- package/dist/domain/protocolCapture.js +243 -0
- package/dist/domain/providerCleanupError.js +11 -0
- package/dist/domain/reconstructionObligationLedgerSchemas.js +278 -0
- package/dist/domain/reconstructionReadiness.js +121 -0
- package/dist/domain/reconstructionReadinessFindingHelpers.js +17 -0
- package/dist/domain/reconstructionReadinessIntegrityFindings.js +118 -0
- package/dist/domain/reconstructionReadinessJourneyFindings.js +193 -0
- package/dist/domain/reconstructionReadinessSchemas.js +240 -0
- package/dist/domain/sourceToBundleComparison.js +335 -0
- package/dist/domain/sourceToBundleComparisonSchemas.js +133 -0
- package/dist/domain/sourceToBundleSignals.js +202 -0
- package/dist/domain/webCaptureDiff.js +141 -27
- package/dist/domain/webScreenshot.js +1 -1
- package/dist/dotnet/ManagedStaticProvider.js +34 -5
- package/dist/generatedMcpToolCatalog.js +37 -0
- package/dist/generatedPackageMetadata.js +4 -4
- package/dist/ghidra/GhidraDefaults.js +1 -1
- package/dist/ghidra/GhidraFunctionValues.js +40 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +47 -38
- package/dist/hopper/HopperCleanup.js +158 -0
- package/dist/hopper/HopperClient.js +93 -99
- package/dist/hopper/HopperProvider.js +61 -30
- package/dist/hopper/HopperRequestQueue.js +215 -0
- package/dist/hopper/HopperResponseStream.js +46 -0
- package/dist/hopper/protocol.js +63 -20
- package/dist/main/transport.js +24 -27
- package/dist/main.js +14 -6
- package/dist/mcpDoctor.js +27 -4
- package/dist/mcpStartupPolicy.js +14 -0
- package/dist/process/ProcessCommandIdentity.js +19 -0
- package/dist/process/ProcessOwnership.js +11 -8
- package/dist/server/DynamicToolAvailability.js +70 -0
- package/dist/server/LazyToolCatalog.js +134 -0
- package/dist/server/createServer.js +92 -154
- package/dist/server/hydrateServerTools.js +191 -0
- package/dist/server/lifecycleProgress.js +10 -0
- package/dist/server/permissionFailure.js +12 -0
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +35 -0
- package/dist/server/registerApplicationTools/helpers.js +11 -7
- package/dist/server/registerApplicationTools/obligationLedger.js +27 -0
- package/dist/server/registerApplicationTools/readiness.js +55 -0
- package/dist/server/registerApplicationTools.js +6 -0
- package/dist/server/registerArtifactTools.js +9 -1
- package/dist/server/registerBrowserScenarioTool.js +25 -0
- package/dist/server/registerBrowserTools.js +2 -2
- package/dist/server/registerCloseLifecycleTool.js +57 -0
- package/dist/server/registerEnhancedTools.js +28 -7
- package/dist/server/registerEvidenceResources.js +54 -101
- package/dist/server/registerEvidenceTools.js +9 -2
- package/dist/server/registerInvestigationTools.js +1 -2
- package/dist/server/registerJavaScriptApplicationGraphResource.js +0 -4
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +37 -0
- package/dist/server/registerReconstructionObligationLedgerResource.js +32 -0
- package/dist/server/registerReconstructionReadinessResource.js +32 -0
- package/dist/server/registerSessionRecordTools.js +82 -12
- package/dist/server/registerSessionStatusTool.js +11 -8
- package/dist/server/registerSessionTools.js +32 -58
- package/dist/server/sessionAvailabilityPolicy.js +10 -8
- package/dist/server/toolRegistrationOptions.js +21 -6
- package/dist/server/toolResult.js +12 -0
- package/package.json +28 -11
- package/scripts/package-runner-bootstrap.mjs +72 -0
- package/scripts/rea.mjs +11 -1
- package/skills/reverse-engineer-anything/SKILL.md +10 -3
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ResourceNotFoundError, ResourceTemplate, } from "@modelcontextprotocol/server";
|
|
2
|
+
import { reconstructionObligationLedgerPageSchema } from "../domain/reconstructionObligationLedgerSchemas.js";
|
|
3
|
+
/** Expose retained obligation-ledger pages as typed Evidence resources. */
|
|
4
|
+
export const registerReconstructionObligationLedgerResource = (server, session) => {
|
|
5
|
+
server.registerResource("reconstruction-obligation-ledger-page", new ResourceTemplate("rea://evidence/{evidenceId}/reconstruction-obligation-ledger", {
|
|
6
|
+
list: undefined,
|
|
7
|
+
}), {
|
|
8
|
+
title: "Reconstruction obligation ledger page",
|
|
9
|
+
description: "One deterministic Evidence v2-backed obligation page with full-ledger closure digest and summaries.",
|
|
10
|
+
mimeType: "application/json",
|
|
11
|
+
}, (uri, variables) => {
|
|
12
|
+
const evidenceId = variables.evidenceId;
|
|
13
|
+
if (typeof evidenceId !== "string")
|
|
14
|
+
throw new ResourceNotFoundError(uri.href);
|
|
15
|
+
const evidence = session.evidenceById(evidenceId);
|
|
16
|
+
if (evidence === undefined ||
|
|
17
|
+
evidence.predicate_type !== "rea.reconstruction-obligation-ledger/v1")
|
|
18
|
+
throw new ResourceNotFoundError(uri.href);
|
|
19
|
+
const page = reconstructionObligationLedgerPageSchema.safeParse(evidence.normalized_result);
|
|
20
|
+
if (!page.success)
|
|
21
|
+
throw new ResourceNotFoundError(uri.href);
|
|
22
|
+
return {
|
|
23
|
+
contents: [
|
|
24
|
+
{
|
|
25
|
+
uri: uri.href,
|
|
26
|
+
mimeType: "application/json",
|
|
27
|
+
text: JSON.stringify({ evidence_id: evidence.evidence_id, page: page.data }, null, 2),
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ResourceNotFoundError, ResourceTemplate, } from "@modelcontextprotocol/server";
|
|
2
|
+
import { reconstructionReadinessReportSchema } from "../domain/reconstructionReadinessSchemas.js";
|
|
3
|
+
/** Expose retained full readiness reports outside compact tool responses. */
|
|
4
|
+
export const registerReconstructionReadinessResource = (server, session) => {
|
|
5
|
+
server.registerResource("reconstruction-readiness-report", new ResourceTemplate("rea://evidence/{evidenceId}/reconstruction-readiness-report", {
|
|
6
|
+
list: undefined,
|
|
7
|
+
}), {
|
|
8
|
+
title: "Reconstruction readiness report",
|
|
9
|
+
description: "Full deterministic nine-stage conformance report and replay identity.",
|
|
10
|
+
mimeType: "application/json",
|
|
11
|
+
}, (uri, variables) => {
|
|
12
|
+
const evidenceId = variables.evidenceId;
|
|
13
|
+
if (typeof evidenceId !== "string")
|
|
14
|
+
throw new ResourceNotFoundError(uri.href);
|
|
15
|
+
const evidence = session.evidenceById(evidenceId);
|
|
16
|
+
if (evidence === undefined ||
|
|
17
|
+
evidence.predicate_type !== "rea.reconstruction-readiness-report/v1")
|
|
18
|
+
throw new ResourceNotFoundError(uri.href);
|
|
19
|
+
const report = reconstructionReadinessReportSchema.safeParse(evidence.normalized_result);
|
|
20
|
+
if (!report.success)
|
|
21
|
+
throw new ResourceNotFoundError(uri.href);
|
|
22
|
+
return {
|
|
23
|
+
contents: [
|
|
24
|
+
{
|
|
25
|
+
uri: uri.href,
|
|
26
|
+
mimeType: "application/json",
|
|
27
|
+
text: JSON.stringify({ evidence_id: evidence.evidence_id, report: report.data }, null, 2),
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readEvidenceBundle, writeEvidenceBundle, } from "../application/EvidenceBundleFiles.js";
|
|
2
|
-
import { exportEvidenceBundleInputSchema, importEvidenceBundleInputSchema, listUnknownsInputSchema, SESSION_TOOL_CONTRACTS, verifyUnknownResolutionInputSchema, } from "../contracts/toolContracts.js";
|
|
2
|
+
import { exportEvidenceBundleInputSchema, importEvidenceBundleInputSchema, listUnknownsInputSchema, snapshotEvidenceBundleInputSchema, SESSION_TOOL_CONTRACTS, verifyUnknownResolutionInputSchema, } from "../contracts/toolContracts.js";
|
|
3
3
|
import { AnalysisProtocolError, PermissionRequiredError, } from "../domain/errors.js";
|
|
4
4
|
import { recordUnknownInputSchema, updateUnknownInputSchema, } from "../domain/residualUnknown.js";
|
|
5
5
|
import { err, ok } from "../domain/result.js";
|
|
@@ -10,6 +10,7 @@ import { toCallToolResult } from "./toolResult.js";
|
|
|
10
10
|
export const registerEvidenceTools = (registration) => {
|
|
11
11
|
registerExportEvidenceTool(registration);
|
|
12
12
|
registerImportEvidenceTool(registration);
|
|
13
|
+
registerSnapshotEvidenceTool(registration);
|
|
13
14
|
};
|
|
14
15
|
const registerExportEvidenceTool = ({ server, session, exportContract, filePolicy, permissionAuthority, }) => {
|
|
15
16
|
server.registerTool(exportContract.name, toolRegistrationOptions(exportContract), async (input) => {
|
|
@@ -18,8 +19,6 @@ const registerExportEvidenceTool = ({ server, session, exportContract, filePolic
|
|
|
18
19
|
return toCallToolResult(parsedInput, exportContract);
|
|
19
20
|
const parsed = parsedInput.value;
|
|
20
21
|
const bundle = session.exportEvidenceBundle();
|
|
21
|
-
if (parsed.path === undefined)
|
|
22
|
-
return toCallToolResult(ok(bundle), exportContract);
|
|
23
22
|
const denied = await authorizeEvidencePath({
|
|
24
23
|
authority: permissionAuthority,
|
|
25
24
|
capability: "evidence_write",
|
|
@@ -35,10 +34,38 @@ const registerExportEvidenceTool = ({ server, session, exportContract, filePolic
|
|
|
35
34
|
path: written.value.path,
|
|
36
35
|
bytes: written.value.bytes,
|
|
37
36
|
records: bundle.records.length,
|
|
37
|
+
unknowns: bundle.unknowns.length,
|
|
38
38
|
}), exportContract)
|
|
39
39
|
: toCallToolResult(written, exportContract);
|
|
40
40
|
});
|
|
41
41
|
};
|
|
42
|
+
const registerSnapshotEvidenceTool = ({ server, session, snapshotContract, }) => {
|
|
43
|
+
server.registerTool(snapshotContract.name, toolRegistrationOptions(snapshotContract), (input) => {
|
|
44
|
+
const parsed = safeParseToolInput(snapshotEvidenceBundleInputSchema, input, snapshotContract.name);
|
|
45
|
+
if (!parsed.ok)
|
|
46
|
+
return toCallToolResult(parsed, snapshotContract);
|
|
47
|
+
const snapshot = session.snapshotEvidenceBundle();
|
|
48
|
+
if (!snapshot.ok)
|
|
49
|
+
return toCallToolResult(snapshot, snapshotContract);
|
|
50
|
+
const value = {
|
|
51
|
+
bundle_digest: snapshot.value.bundleDigest,
|
|
52
|
+
bundle_version: snapshot.value.bundleVersion,
|
|
53
|
+
bytes: snapshot.value.bytes,
|
|
54
|
+
records: snapshot.value.records,
|
|
55
|
+
unknowns: snapshot.value.unknowns,
|
|
56
|
+
bundle_uri: snapshot.value.uri,
|
|
57
|
+
};
|
|
58
|
+
return toCallToolResult(ok(value), snapshotContract, {
|
|
59
|
+
resourceLinks: [
|
|
60
|
+
{
|
|
61
|
+
uri: snapshot.value.uri,
|
|
62
|
+
name: snapshot.value.bundleDigest,
|
|
63
|
+
description: "Immutable session-retained Evidence v2 bundle",
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
};
|
|
42
69
|
const registerImportEvidenceTool = ({ server, session, importContract, filePolicy, permissionAuthority, }) => {
|
|
43
70
|
server.registerTool(importContract.name, toolRegistrationOptions(importContract), async (input) => {
|
|
44
71
|
const parsedInput = safeParseToolInput(importEvidenceBundleInputSchema, input, importContract.name);
|
|
@@ -58,8 +85,6 @@ const registerImportEvidenceTool = ({ server, session, importContract, filePolic
|
|
|
58
85
|
if (!loaded.ok)
|
|
59
86
|
return toCallToolResult(loaded, importContract);
|
|
60
87
|
const imported = session.importEvidenceBundle(loaded.value);
|
|
61
|
-
if (imported.ok && imported.value > 0)
|
|
62
|
-
server.sendResourceListChanged();
|
|
63
88
|
return imported.ok
|
|
64
89
|
? toCallToolResult(ok({
|
|
65
90
|
imported: imported.value,
|
|
@@ -93,22 +118,53 @@ export const registerUnknownTools = ({ server, session, contracts, }) => {
|
|
|
93
118
|
if (!parsed.ok)
|
|
94
119
|
return toCallToolResult(parsed, listContract);
|
|
95
120
|
const filters = parsed.value;
|
|
96
|
-
|
|
121
|
+
const all = session.listUnknowns({
|
|
97
122
|
...(filters.status === undefined ? {} : { status: filters.status }),
|
|
98
123
|
...(filters.severity === undefined
|
|
99
124
|
? {}
|
|
100
125
|
: { severity: filters.severity }),
|
|
101
126
|
...(filters.domain === undefined ? {} : { domain: filters.domain }),
|
|
102
|
-
})
|
|
127
|
+
});
|
|
128
|
+
const items = all
|
|
129
|
+
.slice(filters.offset, filters.offset + filters.limit)
|
|
130
|
+
.map((unknown) => ({
|
|
131
|
+
unknown,
|
|
132
|
+
uri: `rea://unknown/${unknown.unknown_id}`,
|
|
133
|
+
}));
|
|
134
|
+
const nextOffset = filters.offset + items.length < all.length
|
|
135
|
+
? filters.offset + items.length
|
|
136
|
+
: null;
|
|
137
|
+
return toCallToolResult(ok({
|
|
138
|
+
items,
|
|
139
|
+
offset: filters.offset,
|
|
140
|
+
limit: filters.limit,
|
|
141
|
+
total: all.length,
|
|
142
|
+
next_offset: nextOffset,
|
|
143
|
+
has_more: nextOffset !== null,
|
|
144
|
+
}), listContract, {
|
|
145
|
+
resourceLinks: items.map((unknown) => ({
|
|
146
|
+
uri: unknown.uri,
|
|
147
|
+
name: unknown.unknown.unknown_id,
|
|
148
|
+
description: `Current ${unknown.unknown.status} residual unknown revision`,
|
|
149
|
+
})),
|
|
150
|
+
});
|
|
103
151
|
});
|
|
104
152
|
server.registerTool(recordContract.name, toolRegistrationOptions(recordContract), (input) => {
|
|
105
153
|
const parsed = safeParseToolInput(recordUnknownInputSchema, input, recordContract.name);
|
|
106
154
|
if (!parsed.ok)
|
|
107
155
|
return toCallToolResult(parsed, recordContract);
|
|
108
156
|
const result = session.recordUnknown(parsed.value);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
157
|
+
return result.ok
|
|
158
|
+
? toCallToolResult(result, recordContract, {
|
|
159
|
+
resourceLinks: [
|
|
160
|
+
{
|
|
161
|
+
uri: `rea://unknown/${result.value.unknown_id}`,
|
|
162
|
+
name: result.value.unknown_id,
|
|
163
|
+
description: "Current residual unknown head",
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
})
|
|
167
|
+
: toCallToolResult(result, recordContract);
|
|
112
168
|
});
|
|
113
169
|
server.registerTool(updateContract.name, toolRegistrationOptions(updateContract), (input) => {
|
|
114
170
|
const parsed = safeParseToolInput(updateUnknownInputSchema, input, updateContract.name);
|
|
@@ -116,8 +172,22 @@ export const registerUnknownTools = ({ server, session, contracts, }) => {
|
|
|
116
172
|
return toCallToolResult(parsed, updateContract);
|
|
117
173
|
const result = session.updateUnknown(parsed.value);
|
|
118
174
|
if (result.ok)
|
|
119
|
-
server.
|
|
120
|
-
|
|
175
|
+
void server.server
|
|
176
|
+
.sendResourceUpdated({
|
|
177
|
+
uri: `rea://unknown/${result.value.unknown_id}`,
|
|
178
|
+
})
|
|
179
|
+
.catch(() => undefined);
|
|
180
|
+
return result.ok
|
|
181
|
+
? toCallToolResult(result, updateContract, {
|
|
182
|
+
resourceLinks: [
|
|
183
|
+
{
|
|
184
|
+
uri: `rea://unknown/${result.value.unknown_id}`,
|
|
185
|
+
name: result.value.unknown_id,
|
|
186
|
+
description: "Updated residual unknown head",
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
})
|
|
190
|
+
: toCallToolResult(result, updateContract);
|
|
121
191
|
});
|
|
122
192
|
server.registerTool(verifyContract.name, toolRegistrationOptions(verifyContract), (input) => {
|
|
123
193
|
const parsed = safeParseToolInput(verifyUnknownResolutionInputSchema, input, verifyContract.name);
|
|
@@ -15,9 +15,15 @@ export const registerSessionStatusTool = (options) => {
|
|
|
15
15
|
const parsed = parsedInput.value;
|
|
16
16
|
const client = server.server.getClientVersion();
|
|
17
17
|
const clientCapabilities = server.server.getClientCapabilities();
|
|
18
|
+
const clientFeatures = {
|
|
19
|
+
elicitation_form: clientCapabilities?.elicitation?.form !== undefined,
|
|
20
|
+
elicitation_url: clientCapabilities?.elicitation?.url !== undefined,
|
|
21
|
+
roots: clientCapabilities?.roots !== undefined,
|
|
22
|
+
sampling: clientCapabilities?.sampling !== undefined,
|
|
23
|
+
};
|
|
18
24
|
const status = session.status();
|
|
19
25
|
const statusObject = jsonObjectSchema.parse(status);
|
|
20
|
-
const toolAvailability = buildCapabilityInventory(status, availabilityPolicy());
|
|
26
|
+
const toolAvailability = buildCapabilityInventory(status, availabilityPolicy(), clientFeatures);
|
|
21
27
|
const serverIdentity = createServerIdentity({
|
|
22
28
|
startedAt,
|
|
23
29
|
expected: {
|
|
@@ -45,12 +51,7 @@ export const registerSessionStatusTool = (options) => {
|
|
|
45
51
|
status: statusObject,
|
|
46
52
|
toolAvailability,
|
|
47
53
|
serverIdentity,
|
|
48
|
-
clientFeatures
|
|
49
|
-
elicitation_form: clientCapabilities?.elicitation?.form !== undefined,
|
|
50
|
-
elicitation_url: clientCapabilities?.elicitation?.url !== undefined,
|
|
51
|
-
roots: clientCapabilities?.roots !== undefined,
|
|
52
|
-
sampling: clientCapabilities?.sampling !== undefined,
|
|
53
|
-
},
|
|
54
|
+
clientFeatures,
|
|
54
55
|
}),
|
|
55
56
|
}, contract);
|
|
56
57
|
});
|
|
@@ -86,6 +87,7 @@ const projectSessionStatus = (options) => {
|
|
|
86
87
|
next_cursor: nextCursor < filtered.length ? nextCursor : null,
|
|
87
88
|
has_more: nextCursor < filtered.length,
|
|
88
89
|
},
|
|
90
|
+
client_features: options.clientFeatures,
|
|
89
91
|
});
|
|
90
92
|
}
|
|
91
93
|
return jsonObjectSchema.parse({
|
|
@@ -95,6 +97,7 @@ const projectSessionStatus = (options) => {
|
|
|
95
97
|
active_provider: activeProvider,
|
|
96
98
|
target: open ? targetFrom(options.status) : null,
|
|
97
99
|
alignment: options.serverIdentity.alignment,
|
|
100
|
+
analysis_activity: options.status.analysis_activity,
|
|
98
101
|
recommended_actions: recommendedActions(open, options.serverIdentity.alignment.state),
|
|
99
102
|
});
|
|
100
103
|
};
|
|
@@ -115,7 +118,7 @@ const recommendedActions = (open, alignment) => [
|
|
|
115
118
|
: []),
|
|
116
119
|
...(!open
|
|
117
120
|
? [
|
|
118
|
-
"
|
|
121
|
+
"For a supplied target, route by format: ASAR/JavaScript to analyze_javascript_application; archive/package to open_binary(path), then inspect_artifact or inventory_artifact on the active target; managed PE/CLI to inspect_managed_artifact; browser/Electron runtimes to their list-target tools; native binaries to open_binary.",
|
|
119
122
|
]
|
|
120
123
|
: [
|
|
121
124
|
"Continue from the active target with binary_overview or a bounded target-specific query.",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { SESSION_TOOL_CONTRACTS } from "../contracts/toolContracts.js";
|
|
2
|
+
import { addressContextInputSchema, navigationContextInputSchema, SESSION_TOOL_CONTRACTS, } from "../contracts/toolContracts.js";
|
|
3
3
|
import { toCallToolResult } from "./toolResult.js";
|
|
4
4
|
import { logToolExecution } from "./toolLogging.js";
|
|
5
|
-
import {
|
|
5
|
+
import { ok } from "../domain/result.js";
|
|
6
6
|
import { processScenarioSchema } from "../domain/processCapture.js";
|
|
7
7
|
import { captureProcessScenario } from "../application/ProcessHarness.js";
|
|
8
8
|
import { processCapturePermissionRequest } from "../application/ProcessCapturePermission.js";
|
|
9
|
-
import { readAnalysisSnapshot
|
|
10
|
-
import {
|
|
9
|
+
import { readAnalysisSnapshot } from "../application/AnalysisSnapshotFiles.js";
|
|
10
|
+
import { UnknownRegistryError } from "../domain/errors.js";
|
|
11
11
|
import { DENY_EVIDENCE_FILE_POLICY, DENY_PROCESS_POLICY, } from "./sessionToolPolicies.js";
|
|
12
12
|
import { createProcessCaptureEvidence } from "../application/ProcessEvidence.js";
|
|
13
13
|
import { registerProcessComparisonTool } from "./registerProcessComparisonTool.js";
|
|
@@ -17,7 +17,7 @@ import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
|
|
|
17
17
|
import { safeParseToolInput } from "./toolInputValidation.js";
|
|
18
18
|
import { registerBundleComparisonTool } from "./registerBundleComparisonTool.js";
|
|
19
19
|
import { registerInvestigationTools } from "./registerInvestigationTools.js";
|
|
20
|
-
import {
|
|
20
|
+
import { openBinaryInputSchema } from "../contracts/sessionLifecycleInputs.js";
|
|
21
21
|
import { registerSessionStatusTool } from "./registerSessionStatusTool.js";
|
|
22
22
|
import { mcpProgressReporter } from "./mcpProgress.js";
|
|
23
23
|
import { authorizeProcessCaptureWithElicitation, } from "./ProcessCaptureElicitation.js";
|
|
@@ -25,15 +25,9 @@ import { isInputRequiredResult } from "@modelcontextprotocol/server";
|
|
|
25
25
|
import { registerEvidenceTools, registerUnknownTools, } from "./registerSessionRecordTools.js";
|
|
26
26
|
import { registerReplayMachineTool } from "./registerReplayMachineTool.js";
|
|
27
27
|
import { sessionAvailabilityPolicy, } from "./sessionAvailabilityPolicy.js";
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return err(failure.error instanceof PermissionRequiredError
|
|
32
|
-
? failure.error
|
|
33
|
-
: new AnalysisProtocolError(failure.error.message, {
|
|
34
|
-
cause: failure.error,
|
|
35
|
-
}));
|
|
36
|
-
};
|
|
28
|
+
import { permissionFailure } from "./permissionFailure.js";
|
|
29
|
+
import { registerCloseLifecycleTool } from "./registerCloseLifecycleTool.js";
|
|
30
|
+
import { getNavigationContext, inspectAddressContext, } from "../application/AnalysisContextQueries.js";
|
|
37
31
|
const recordProcessResidualUnknowns = (session, scenario, evidence, residuals) => {
|
|
38
32
|
if (scenario.unknown_registry_approved !== true)
|
|
39
33
|
return ok(null);
|
|
@@ -170,49 +164,6 @@ const registerOpenLifecycleTool = ({ server, session, logger, contracts: [openCo
|
|
|
170
164
|
: toCallToolResult(opened, openContract);
|
|
171
165
|
});
|
|
172
166
|
};
|
|
173
|
-
const registerCloseLifecycleTool = ({ server, session, logger, contracts: [, closeContract], snapshotFilePolicy, permissionAuthority, }) => {
|
|
174
|
-
server.registerTool(closeContract.name, toolRegistrationOptions(closeContract), async (input) => {
|
|
175
|
-
const parsedInput = safeParseToolInput(closeBinaryInputSchema, input, closeContract.name);
|
|
176
|
-
if (!parsedInput.ok)
|
|
177
|
-
return toCallToolResult(parsedInput, closeContract);
|
|
178
|
-
const parsed = parsedInput.value;
|
|
179
|
-
if (parsed.snapshot_path === undefined) {
|
|
180
|
-
const closed = await logToolExecution(logger, closeContract.name, () => session.close());
|
|
181
|
-
if (closed.ok)
|
|
182
|
-
server.sendToolListChanged();
|
|
183
|
-
return toCallToolResult(closed, closeContract);
|
|
184
|
-
}
|
|
185
|
-
if (permissionAuthority !== undefined) {
|
|
186
|
-
const authorized = await permissionAuthority.authorize({
|
|
187
|
-
capability: "snapshot_write",
|
|
188
|
-
roots: [parsed.snapshot_path],
|
|
189
|
-
executables: [],
|
|
190
|
-
environment_names: [],
|
|
191
|
-
network: "none",
|
|
192
|
-
mount: false,
|
|
193
|
-
operation_identity: `close_binary:snapshot:${parsed.snapshot_path}`,
|
|
194
|
-
}, "write");
|
|
195
|
-
if (!authorized.ok)
|
|
196
|
-
return toCallToolResult(permissionFailure(authorized), closeContract);
|
|
197
|
-
}
|
|
198
|
-
const snapshot = session.exportAnalysisSnapshot();
|
|
199
|
-
if (!snapshot.ok)
|
|
200
|
-
return toCallToolResult(snapshot, closeContract);
|
|
201
|
-
const written = await writeAnalysisSnapshot(snapshot.value, parsed.snapshot_path, parsed.overwrite, snapshotFilePolicy);
|
|
202
|
-
if (!written.ok)
|
|
203
|
-
return toCallToolResult(written, closeContract);
|
|
204
|
-
const closed = await logToolExecution(logger, closeContract.name, () => session.close());
|
|
205
|
-
if (closed.ok)
|
|
206
|
-
server.sendToolListChanged();
|
|
207
|
-
return closed.ok
|
|
208
|
-
? toCallToolResult(ok({
|
|
209
|
-
path: written.value.path,
|
|
210
|
-
bytes: written.value.bytes,
|
|
211
|
-
entries: snapshot.value.entries.length,
|
|
212
|
-
}), closeContract)
|
|
213
|
-
: toCallToolResult(closed, closeContract);
|
|
214
|
-
});
|
|
215
|
-
};
|
|
216
167
|
const registerRecordAndReplayTools = (server, session, logger) => {
|
|
217
168
|
registerUnknownTools({
|
|
218
169
|
server,
|
|
@@ -221,11 +172,28 @@ const registerRecordAndReplayTools = (server, session, logger) => {
|
|
|
221
172
|
});
|
|
222
173
|
registerReplayMachineTool(server, logger);
|
|
223
174
|
};
|
|
175
|
+
const registerContextTools = (server, session) => {
|
|
176
|
+
const navigationContract = SESSION_TOOL_CONTRACTS[20];
|
|
177
|
+
const addressContract = SESSION_TOOL_CONTRACTS[21];
|
|
178
|
+
server.registerTool(navigationContract.name, toolRegistrationOptions(navigationContract), async (input, context) => {
|
|
179
|
+
const parsed = safeParseToolInput(navigationContextInputSchema, input, navigationContract.name);
|
|
180
|
+
if (!parsed.ok)
|
|
181
|
+
return toCallToolResult(parsed, navigationContract);
|
|
182
|
+
return toCallToolResult(await getNavigationContext(session, parsed.value, context.mcpReq.signal), navigationContract);
|
|
183
|
+
});
|
|
184
|
+
server.registerTool(addressContract.name, toolRegistrationOptions(addressContract), async (input, context) => {
|
|
185
|
+
const parsed = safeParseToolInput(addressContextInputSchema, input, addressContract.name);
|
|
186
|
+
if (!parsed.ok)
|
|
187
|
+
return toCallToolResult(parsed, addressContract);
|
|
188
|
+
return toCallToolResult(await inspectAddressContext(session, parsed.value, context.mcpReq.signal), addressContract);
|
|
189
|
+
});
|
|
190
|
+
};
|
|
224
191
|
export const registerSessionTools = (server, session, logger, options = {}) => {
|
|
225
192
|
const processPolicy = options.processPolicy ?? DENY_PROCESS_POLICY;
|
|
226
193
|
const evidenceFilePolicy = options.evidenceFilePolicy ?? DENY_EVIDENCE_FILE_POLICY;
|
|
227
194
|
const analysisSnapshotFilePolicy = options.analysisSnapshotFilePolicy ?? DENY_EVIDENCE_FILE_POLICY;
|
|
228
195
|
const [openContract, closeContract, statusContract, exportContract, importContract, captureContract, compareContract, compareArtifactsContract, compareFunctionsContract, compareBundlesContract, changedBehaviorContract, callPathContract, staticRuntimeContract, reconstructionContract,] = SESSION_TOOL_CONTRACTS;
|
|
196
|
+
const snapshotContract = SESSION_TOOL_CONTRACTS[19];
|
|
229
197
|
registerLifecycleTools({
|
|
230
198
|
server,
|
|
231
199
|
session,
|
|
@@ -233,7 +201,11 @@ export const registerSessionTools = (server, session, logger, options = {}) => {
|
|
|
233
201
|
contracts: [openContract, closeContract, statusContract],
|
|
234
202
|
snapshotFilePolicy: analysisSnapshotFilePolicy,
|
|
235
203
|
startedAt: options.startedAt ?? new Date().toISOString(),
|
|
236
|
-
availabilityPolicy: sessionAvailabilityPolicy(options.availabilityPolicy,
|
|
204
|
+
availabilityPolicy: sessionAvailabilityPolicy(options.availabilityPolicy, {
|
|
205
|
+
processPolicy,
|
|
206
|
+
evidenceFilePolicy,
|
|
207
|
+
investigationInputRoots: options.investigationInputRoots ?? [],
|
|
208
|
+
}),
|
|
237
209
|
...(options.permissionAuthority === undefined
|
|
238
210
|
? {}
|
|
239
211
|
: { permissionAuthority: options.permissionAuthority }),
|
|
@@ -243,6 +215,7 @@ export const registerSessionTools = (server, session, logger, options = {}) => {
|
|
|
243
215
|
session,
|
|
244
216
|
exportContract,
|
|
245
217
|
importContract,
|
|
218
|
+
snapshotContract,
|
|
246
219
|
filePolicy: evidenceFilePolicy,
|
|
247
220
|
...(options.permissionAuthority === undefined
|
|
248
221
|
? {}
|
|
@@ -284,4 +257,5 @@ export const registerSessionTools = (server, session, logger, options = {}) => {
|
|
|
284
257
|
: { permissionAuthority: options.permissionAuthority }),
|
|
285
258
|
});
|
|
286
259
|
registerRecordAndReplayTools(server, session, logger);
|
|
260
|
+
registerContextTools(server, session);
|
|
287
261
|
};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/** Select configured availability reporting or the target-free defaults. */
|
|
2
|
-
export const sessionAvailabilityPolicy = (configured,
|
|
2
|
+
export const sessionAvailabilityPolicy = (configured, defaults) => configured ??
|
|
3
3
|
(() => ({
|
|
4
|
-
processCaptureEnabled: processPolicy.enabled,
|
|
5
|
-
evidenceFileRoots: evidenceFilePolicy.roots.length,
|
|
6
|
-
investigationInputRoots: investigationInputRoots.length,
|
|
7
|
-
browserObservationEnabled: false,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
processCaptureEnabled: defaults.processPolicy.enabled,
|
|
5
|
+
evidenceFileRoots: defaults.evidenceFilePolicy.roots.length,
|
|
6
|
+
investigationInputRoots: defaults.investigationInputRoots.length,
|
|
7
|
+
browserObservationEnabled: defaults.optionalFeatures?.browserObservationEnabled ?? false,
|
|
8
|
+
browserScenarioEnabled: defaults.optionalFeatures?.browserScenarioEnabled ?? false,
|
|
9
|
+
electronObservationEnabled: defaults.optionalFeatures?.electronObservationEnabled ?? false,
|
|
10
|
+
v8InspectorObservationEnabled: defaults.optionalFeatures?.v8InspectorObservationEnabled ?? false,
|
|
11
|
+
javascriptReplayEnabled: defaults.optionalFeatures?.javascriptReplayEnabled ?? false,
|
|
12
|
+
managedRuntimeEnabled: defaults.optionalFeatures?.managedRuntimeEnabled ?? false,
|
|
11
13
|
}));
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
const ADVERTISED_INPUT_SCHEMAS = new WeakMap();
|
|
3
|
+
const ADVERTISED_OUTPUT_SCHEMAS = new WeakMap();
|
|
2
4
|
/** Project the public contract fields accepted by MCP tool registration. */
|
|
3
5
|
export const toolRegistrationOptions = (contract) => ({
|
|
4
6
|
title: contract.title,
|
|
5
7
|
description: contract.description,
|
|
6
|
-
inputSchema: advertisedInputSchema(contract
|
|
8
|
+
inputSchema: advertisedInputSchema(contract),
|
|
7
9
|
outputSchema: advertisedOutputSchema(contract.outputSchema),
|
|
8
10
|
annotations: contract.annotations,
|
|
9
11
|
});
|
|
@@ -12,14 +14,14 @@ export const toolRegistrationOptions = (contract) => ({
|
|
|
12
14
|
* The SDK otherwise converts validation failures to text-only JSON-RPC errors
|
|
13
15
|
* before REA can return its stable structured error envelope.
|
|
14
16
|
*/
|
|
15
|
-
const advertisedInputSchema = (
|
|
17
|
+
const advertisedInputSchema = (contract) => ({
|
|
16
18
|
"~standard": {
|
|
17
19
|
version: 1,
|
|
18
20
|
vendor: "rea",
|
|
19
21
|
validate: (input) => ({ value: input }),
|
|
20
22
|
jsonSchema: {
|
|
21
|
-
input: () =>
|
|
22
|
-
output: () =>
|
|
23
|
+
input: () => advertisedInputJsonSchema(contract),
|
|
24
|
+
output: () => advertisedInputJsonSchema(contract),
|
|
23
25
|
},
|
|
24
26
|
},
|
|
25
27
|
});
|
|
@@ -32,12 +34,25 @@ const advertisedOutputSchema = (schema) => {
|
|
|
32
34
|
"~standard": {
|
|
33
35
|
...standard,
|
|
34
36
|
jsonSchema: {
|
|
35
|
-
input: () =>
|
|
36
|
-
output: () =>
|
|
37
|
+
input: () => advertisedOutputJsonSchema(schema, converter),
|
|
38
|
+
output: () => advertisedOutputJsonSchema(schema, converter),
|
|
37
39
|
},
|
|
38
40
|
},
|
|
39
41
|
};
|
|
40
42
|
};
|
|
43
|
+
const advertisedInputJsonSchema = (contract) => cachedJsonSchema(ADVERTISED_INPUT_SCHEMAS, contract.inputSchema, () => ({
|
|
44
|
+
...describeProperties(closeObjectSchemas(inputJsonSchema(contract.inputSchema))),
|
|
45
|
+
examples: contract.examples.map(({ input }) => input),
|
|
46
|
+
}));
|
|
47
|
+
const advertisedOutputJsonSchema = (schema, converter) => cachedJsonSchema(ADVERTISED_OUTPUT_SCHEMAS, schema, () => describeRootProperties(closeObjectSchemas(converter({ target: "draft-2020-12" }))));
|
|
48
|
+
const cachedJsonSchema = (cache, schema, create) => {
|
|
49
|
+
const cached = cache.get(schema);
|
|
50
|
+
if (cached !== undefined)
|
|
51
|
+
return cached;
|
|
52
|
+
const created = create();
|
|
53
|
+
cache.set(schema, created);
|
|
54
|
+
return created;
|
|
55
|
+
};
|
|
41
56
|
const inputJsonSchema = (schema) => {
|
|
42
57
|
const converter = schema["~standard"].jsonSchema?.input;
|
|
43
58
|
if (converter === undefined)
|
|
@@ -49,6 +49,14 @@ const successResult = (value, contract, options) => {
|
|
|
49
49
|
: (compactEvidence(value, options.evidenceTextProjection) ??
|
|
50
50
|
options.evidenceTextProjection)),
|
|
51
51
|
},
|
|
52
|
+
...(hasResourceLinks(value, contract, options)
|
|
53
|
+
? [
|
|
54
|
+
{
|
|
55
|
+
type: "text",
|
|
56
|
+
text: "Full detail is available through MCP resources/read. Copy the opaque URI exactly. In Codex, call read_mcp_resource.",
|
|
57
|
+
},
|
|
58
|
+
]
|
|
59
|
+
: []),
|
|
52
60
|
...evidenceResourceLinks(value, contract.kind === "session" ||
|
|
53
61
|
options.evidenceResourcesAvailable === true),
|
|
54
62
|
...(options.resourceLinks ?? []).map((resource) => ({
|
|
@@ -60,6 +68,10 @@ const successResult = (value, contract, options) => {
|
|
|
60
68
|
structuredContent: candidate,
|
|
61
69
|
};
|
|
62
70
|
};
|
|
71
|
+
const hasResourceLinks = (value, contract, options) => options.resourceLinks !== undefined && options.resourceLinks.length > 0
|
|
72
|
+
? true
|
|
73
|
+
: evidenceResourceLinks(value, contract.kind === "session" ||
|
|
74
|
+
options.evidenceResourcesAvailable === true).length > 0;
|
|
63
75
|
const compactEvidence = (value, resultProjection) => {
|
|
64
76
|
if (typeof value !== "object" ||
|
|
65
77
|
value === null ||
|