rea-agents 2.0.0 → 2.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 +78 -32
- package/bridge/ghidra/ReaGhidraBridge.java +96 -11
- package/dist/application/ArtifactExtraction.js +1 -1
- package/dist/application/ArtifactInventory/classify.js +42 -0
- package/dist/application/ArtifactInventory/hash.js +43 -0
- package/dist/application/ArtifactInventory/reader.js +41 -0
- package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
- package/dist/application/ArtifactInventory/scanReader.js +124 -0
- package/dist/application/ArtifactInventory/types.js +10 -0
- package/dist/application/ArtifactInventory.js +9 -351
- package/dist/application/AuthorizedArtifactInventory.js +2 -2
- package/dist/application/BinarySession.js +47 -270
- package/dist/application/BinarySessionExecution.js +28 -0
- package/dist/application/BinarySessionOpen.js +39 -0
- package/dist/application/BinarySessionRecords.js +149 -0
- package/dist/application/BinarySessionStatus.js +75 -0
- package/dist/application/CapabilityInventory.js +24 -2
- package/dist/application/ClientRegistrationStatus.js +1 -1
- package/dist/application/CrossVersionInventory.js +8 -2
- package/dist/application/CrossVersionInvestigation.js +1 -23
- package/dist/application/CrossVersionInvestigationCollections.js +23 -0
- package/dist/application/DirectAnalysis.js +47 -44
- package/dist/application/Doctor.js +156 -238
- package/dist/application/DoctorDiagnostics.js +180 -0
- package/dist/application/ElectronBoundaryAnalysis.js +23 -7
- package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
- package/dist/application/EnhancedToolPagination.js +22 -0
- package/dist/application/EnhancedToolTypes.js +4 -0
- package/dist/application/EnhancedTools.js +20 -37
- package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
- package/dist/application/InvestigationWorkspaceStore.js +24 -10
- package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
- package/dist/application/JavaScriptArtifactFiles.js +6 -2
- package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
- package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
- package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
- package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
- package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
- package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
- package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
- package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
- package/dist/application/JavaScriptJsonModules.js +39 -0
- package/dist/application/JavaScriptModuleRelationships.js +262 -0
- package/dist/application/JavaScriptReplayPermission.js +16 -0
- package/dist/application/JavaScriptReplayService.js +182 -156
- package/dist/application/LinuxHopper.js +10 -0
- package/dist/application/MacHopper.js +22 -11
- package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
- package/dist/application/PermissionAuthority.js +106 -63
- package/dist/application/ProcessCaptureCapability.js +1 -1
- package/dist/application/ProcessCapturePermission.js +13 -0
- package/dist/application/ProcessCli.js +2 -12
- package/dist/application/ProcessHarness.js +1 -1
- package/dist/application/ProjectPermissionStore.js +48 -9
- package/dist/application/RealHopperAssertions.js +76 -0
- package/dist/application/ReconstructionCoverageService.js +69 -0
- package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
- package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
- package/dist/application/Setup.js +147 -259
- package/dist/application/SetupClientConfiguration.js +220 -0
- package/dist/application/SetupClients.js +24 -2
- package/dist/application/SetupPlan.js +123 -12
- package/dist/application/SetupSkill.js +26 -12
- package/dist/application/SupportedClients.js +1 -0
- package/dist/application/Uninstall.js +6 -3
- package/dist/application/WindowsCapabilities.js +86 -0
- package/dist/artifacts/AsarArtifactReader.js +11 -0
- package/dist/browser/BrowserProcessStartup.js +88 -0
- package/dist/browser/CdpCaptureDocuments.js +12 -8
- package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
- package/dist/browser/CdpCaptureEventHandlers.js +336 -0
- package/dist/browser/CdpCaptureEventHelpers.js +71 -0
- package/dist/browser/CdpCaptureEventState.js +1 -0
- package/dist/browser/CdpCaptureEventTypes.js +1 -0
- package/dist/browser/CdpCaptureEvents.js +29 -496
- package/dist/browser/CdpObservationSession.js +51 -8
- package/dist/browser/CdpPageCapture.js +12 -133
- package/dist/browser/CdpPageCaptureScripts.js +97 -0
- package/dist/browser/CdpPageCaptureWorkers.js +46 -0
- package/dist/browser/CdpWebMcpDiscovery.js +38 -14
- package/dist/browser/PngVisualDiff.js +9 -2
- package/dist/catalogIdentity.js +4 -0
- package/dist/cli/artifactCommands.js +82 -0
- package/dist/cli/coreAnalysisCommands.js +232 -0
- package/dist/cli/managedCommands.js +397 -0
- package/dist/cli/managedProjectGraphCommand.js +24 -0
- package/dist/cli/options.js +9 -0
- package/dist/cli/setupCommands.js +108 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/utilityCommands.js +122 -0
- package/dist/cli.js +10 -768
- package/dist/cliApplicationCommands.js +118 -4
- package/dist/cliBrowserAdvancedCommands.js +73 -16
- package/dist/cliBrowserCommands.js +39 -115
- package/dist/cliCommandNames.js +4 -0
- package/dist/cliElectronCommands.js +33 -62
- package/dist/cliEvidenceCommands.js +13 -2
- package/dist/cliInvestigationCommands.js +53 -10
- package/dist/cliObservationOptions.js +137 -0
- package/dist/cliPolicyCommands.js +80 -46
- package/dist/cliSetup.js +289 -0
- package/dist/config/environment.js +107 -0
- package/dist/config/parseConfig.js +228 -0
- package/dist/config/parsers.js +68 -0
- package/dist/config/permissions.js +30 -0
- package/dist/config/types.js +1 -0
- package/dist/config.js +1 -375
- package/dist/contracts/applicationToolContracts.js +134 -0
- package/dist/contracts/managedToolContracts.js +1 -1
- package/dist/contracts/managedWorkflowToolContracts.js +3 -3
- package/dist/contracts/providerSelection.js +2 -0
- package/dist/contracts/toolContracts.js +2 -2
- package/dist/contracts/toolEffects.js +14 -0
- package/dist/contracts/toolOutputSchemaGroups.js +232 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
- package/dist/contracts/toolOutputSchemas.js +2 -550
- package/dist/domain/analysisErrorPresentation.js +234 -0
- package/dist/domain/analysisErrorProjection.js +284 -0
- package/dist/domain/artifactComparison.js +34 -15
- package/dist/domain/binaryTarget.js +87 -37
- package/dist/domain/browserObservation.js +1 -285
- package/dist/domain/browserObservationSchemas.js +286 -0
- package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
- package/dist/domain/errors.js +4 -486
- package/dist/domain/functionComparison.js +4 -165
- package/dist/domain/functionComparisonDimensions.js +164 -0
- package/dist/domain/javascriptApplicationVersionItems.js +18 -6
- package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
- package/dist/domain/javascriptExportInstrumentation.js +97 -0
- package/dist/domain/javascriptFeatureTraversal.js +19 -7
- package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
- package/dist/domain/javascriptSemanticAnalysis.js +386 -0
- package/dist/domain/javascriptSemanticIr.js +30 -0
- package/dist/domain/javascriptSemanticProjection.js +366 -0
- package/dist/domain/javascriptSemanticState.js +40 -0
- package/dist/domain/javascriptSemanticTraversal.js +22 -0
- package/dist/domain/javascriptSemanticValues.js +352 -0
- package/dist/domain/javascriptStaticAnalysis.js +5 -221
- package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
- package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
- package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
- package/dist/domain/knownPageCoverage.js +21 -0
- package/dist/domain/managedApplicationGraph.js +14 -364
- package/dist/domain/managedApplicationGraphCoverage.js +170 -0
- package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
- package/dist/domain/managedApplicationGraphNodes.js +336 -0
- package/dist/domain/managedArtifact.js +16 -8
- package/dist/domain/managedMemberComparison.js +37 -391
- package/dist/domain/managedMemberComparisonCoverage.js +72 -0
- package/dist/domain/managedMemberComparisonMatch.js +356 -0
- package/dist/domain/managedNativeVerification.js +27 -389
- package/dist/domain/managedNativeVerificationMatch.js +272 -0
- package/dist/domain/managedNativeVerificationSchemas.js +141 -0
- package/dist/domain/managedReconstruction.js +82 -69
- package/dist/domain/managedRuntimeCorrelation.js +12 -3
- package/dist/domain/nodeRuntimeCharacterization.js +66 -0
- package/dist/domain/permissionPolicy.js +2 -0
- package/dist/domain/reconstructionCoverage.js +387 -0
- package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
- package/dist/domain/reconstructionVerificationSchemas.js +8 -0
- package/dist/domain/runtimeCharacterization.js +85 -0
- package/dist/domain/webBundleAnalyzer.js +3 -409
- package/dist/domain/webBundleAnalyzerAst.js +77 -0
- package/dist/domain/webBundleAnalyzerInspection.js +307 -0
- package/dist/domain/webBundleAnalyzerResult.js +120 -0
- package/dist/dotnet/ManagedArtifactInspector.js +50 -29
- package/dist/dotnet/ManagedMemberInspector.js +51 -785
- package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
- package/dist/dotnet/ManagedMemberRows.js +120 -0
- package/dist/dotnet/ManagedMetadataInventory.js +42 -306
- package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
- package/dist/dotnet/ManagedMetadataLayout.js +48 -111
- package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
- package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
- package/dist/dotnet/ManagedPeReader.js +59 -28
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraClient.js +76 -91
- package/dist/ghidra/GhidraClientStartup.js +29 -0
- package/dist/ghidra/GhidraClientWire.js +34 -0
- package/dist/ghidra/GhidraDefaults.js +1 -1
- package/dist/ghidra/GhidraDiagnostics.js +6 -1
- package/dist/ghidra/GhidraInstallation.js +20 -15
- package/dist/ghidra/GhidraLauncher.js +93 -29
- package/dist/ghidra/GhidraProvider.js +61 -161
- package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
- package/dist/ghidra/GhidraSessionValues.js +2 -0
- package/dist/ghidra/GhidraSocketConnection.js +44 -7
- package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
- package/dist/ghidra/GhidraTransport.js +71 -0
- package/dist/identity.js +3 -2
- package/dist/main/messages.js +5 -0
- package/dist/main/reload.js +49 -0
- package/dist/main/shutdown.js +25 -0
- package/dist/main/startup.js +14 -0
- package/dist/main/state.js +26 -0
- package/dist/main/transport.js +61 -0
- package/dist/main/types.js +1 -0
- package/dist/main.js +35 -146
- package/dist/process/PrivateRuntimeRoot.js +3 -2
- package/dist/process/ProcessOwnership.js +35 -0
- package/dist/process/ProviderProcess.js +2 -0
- package/dist/replay/JavaScriptReplayWorker.js +64 -50
- package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
- package/dist/replay/ReplayOutcome.js +95 -0
- package/dist/replay/ReplayProcessLifecycle.js +71 -0
- package/dist/server/ProcessCaptureElicitation.js +157 -0
- package/dist/server/createServer.js +119 -54
- package/dist/server/registerApplicationTools/characterization.js +57 -0
- package/dist/server/registerApplicationTools/compareVersions.js +34 -0
- package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
- package/dist/server/registerApplicationTools/coverage.js +84 -0
- package/dist/server/registerApplicationTools/helpers.js +42 -0
- package/dist/server/registerApplicationTools/traceFeature.js +26 -0
- package/dist/server/registerApplicationTools/types.js +1 -0
- package/dist/server/registerApplicationTools.js +10 -112
- package/dist/server/registerBrowserTools.js +59 -83
- package/dist/server/registerElectronTools.js +31 -46
- package/dist/server/registerEnhancedTools.js +34 -42
- package/dist/server/registerEvidenceResources.js +54 -0
- package/dist/server/registerInvestigationTools/helpers.js +74 -0
- package/dist/server/registerInvestigationTools/types.js +1 -0
- package/dist/server/registerInvestigationTools.js +83 -116
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
- package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
- package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
- package/dist/server/registerManagedWorkflowTools/types.js +1 -0
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
- package/dist/server/registerManagedWorkflowTools.js +10 -274
- package/dist/server/registerOfficialTools.js +73 -59
- package/dist/server/registerSessionRecordTools.js +137 -0
- package/dist/server/registerSessionStatusTool.js +2 -1
- package/dist/server/registerSessionTools.js +60 -164
- package/dist/server/sessionAvailabilityPolicy.js +10 -0
- package/dist/server/toolRegistrationOptions.js +101 -3
- package/dist/server/toolResult.js +5 -0
- package/package.json +10 -11
- package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +20 -7
- package/scripts/prepare-node-pty.mjs +0 -35
- package/scripts/rebuild-native.mjs +0 -22
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { CLIENT_CAPABILITIES_META_KEY, createRequestStateCodec, McpServer, PROTOCOL_VERSION_META_KEY, } from "@modelcontextprotocol/server";
|
|
2
3
|
import { PRODUCT_IDENTITY } from "../identity.js";
|
|
3
4
|
import { registerEnhancedTools } from "./registerEnhancedTools.js";
|
|
4
5
|
import { registerOfficialTools } from "./registerOfficialTools.js";
|
|
@@ -16,6 +17,7 @@ import { registerElectronTools } from "./registerElectronTools.js";
|
|
|
16
17
|
import { registerApplicationTools } from "./registerApplicationTools.js";
|
|
17
18
|
import { LinuxJavaScriptReplayRunner } from "../replay/LinuxJavaScriptReplayRunner.js";
|
|
18
19
|
import { SystemJavaScriptReplayHost } from "../replay/SystemJavaScriptReplayHost.js";
|
|
20
|
+
import { PROCESS_CAPTURE_ELICITATION_POLICY, } from "./ProcessCaptureElicitation.js";
|
|
19
21
|
/**
|
|
20
22
|
* Construct one MCP server without acquiring subprocess resources.
|
|
21
23
|
* Supplying a session adds target lifecycle tools; omitting it retains the
|
|
@@ -24,6 +26,11 @@ import { SystemJavaScriptReplayHost } from "../replay/SystemJavaScriptReplayHost
|
|
|
24
26
|
export const createServer = (analysis, session, options = {}) => {
|
|
25
27
|
const startedAt = new Date().toISOString();
|
|
26
28
|
const logger = options.logger ?? silentLogger;
|
|
29
|
+
const permissionAuthority = options.permissionAuthority?.createConnectionAuthority();
|
|
30
|
+
const processCaptureStateCodec = createRequestStateCodec({
|
|
31
|
+
key: randomBytes(32),
|
|
32
|
+
ttlSeconds: PROCESS_CAPTURE_ELICITATION_POLICY.stateTtlSeconds,
|
|
33
|
+
});
|
|
27
34
|
const server = new McpServer({
|
|
28
35
|
name: PRODUCT_IDENTITY.mcpServerKey,
|
|
29
36
|
version: PRODUCT_IDENTITY.packageVersion,
|
|
@@ -32,17 +39,88 @@ export const createServer = (analysis, session, options = {}) => {
|
|
|
32
39
|
tools: { listChanged: true },
|
|
33
40
|
resources: { listChanged: true },
|
|
34
41
|
},
|
|
42
|
+
inputRequired: {
|
|
43
|
+
maxRounds: 3,
|
|
44
|
+
roundTimeoutMs: PROCESS_CAPTURE_ELICITATION_POLICY.roundTimeoutMs,
|
|
45
|
+
},
|
|
46
|
+
requestState: { verify: processCaptureStateCodec.verify },
|
|
35
47
|
instructions: session === undefined
|
|
36
48
|
? "Reverse-engineering tools for an active analysis target. Start with binary_overview."
|
|
37
49
|
: "Reverse-engineering tools for configured analysis providers. Open a target with open_binary, then start with binary_overview.",
|
|
38
50
|
});
|
|
51
|
+
server.server.onclose = () => {
|
|
52
|
+
permissionAuthority?.clearSessionGrants();
|
|
53
|
+
};
|
|
39
54
|
session?.onAvailabilityChanged?.(() => server.sendToolListChanged());
|
|
55
|
+
registerServerIdentityResource(server, startedAt);
|
|
56
|
+
const toolLogger = logger.child({ layer: "server" });
|
|
57
|
+
const { activeTarget, recordEvidence, recordEvidenceWithUnknown } = createSessionRecorders(server, session);
|
|
58
|
+
const toolContext = {
|
|
59
|
+
server,
|
|
60
|
+
analysis,
|
|
61
|
+
session,
|
|
62
|
+
options,
|
|
63
|
+
logger: toolLogger,
|
|
64
|
+
permissionAuthority,
|
|
65
|
+
activeTarget,
|
|
66
|
+
recordEvidence,
|
|
67
|
+
recordEvidenceWithUnknown,
|
|
68
|
+
};
|
|
69
|
+
registerBinaryAnalysisTools(toolContext);
|
|
70
|
+
registerObservationTools(toolContext);
|
|
71
|
+
registerGuidedPrompts(server, analysis, session);
|
|
72
|
+
if (session !== undefined) {
|
|
73
|
+
registerEvidenceResources(server, session);
|
|
74
|
+
registerSessionTools(server, session, toolLogger, {
|
|
75
|
+
...options,
|
|
76
|
+
...(permissionAuthority === undefined ? {} : { permissionAuthority }),
|
|
77
|
+
startedAt,
|
|
78
|
+
processCaptureElicitation: {
|
|
79
|
+
stateCodec: processCaptureStateCodec,
|
|
80
|
+
supported: (context) => {
|
|
81
|
+
const envelope = context.mcpReq.envelope;
|
|
82
|
+
const version = envelope?.[PROTOCOL_VERSION_META_KEY];
|
|
83
|
+
const capabilities = envelope?.[CLIENT_CAPABILITIES_META_KEY];
|
|
84
|
+
return (typeof version === "string" &&
|
|
85
|
+
PROCESS_CAPTURE_ELICITATION_POLICY.protocolVersions.some((supported) => supported === version) &&
|
|
86
|
+
isRecord(capabilities) &&
|
|
87
|
+
isRecord(capabilities.elicitation) &&
|
|
88
|
+
capabilities.elicitation.form !== undefined);
|
|
89
|
+
},
|
|
90
|
+
now: Date.now,
|
|
91
|
+
consumedNonces: new Map(),
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return server;
|
|
96
|
+
};
|
|
97
|
+
const createSessionRecorders = (server, session) => ({
|
|
98
|
+
activeTarget: session === undefined ? undefined : () => session.activeTarget(),
|
|
99
|
+
recordEvidence: session === undefined
|
|
100
|
+
? undefined
|
|
101
|
+
: (evidence) => {
|
|
102
|
+
const recorded = session.recordEvidence(evidence);
|
|
103
|
+
if (recorded.ok && recorded.value === "added")
|
|
104
|
+
server.sendResourceListChanged();
|
|
105
|
+
return recorded;
|
|
106
|
+
},
|
|
107
|
+
recordEvidenceWithUnknown: session === undefined
|
|
108
|
+
? undefined
|
|
109
|
+
: (evidence, input) => {
|
|
110
|
+
const recorded = session.recordEvidenceWithUnknown(evidence, input);
|
|
111
|
+
if (recorded.ok)
|
|
112
|
+
server.sendResourceListChanged();
|
|
113
|
+
return recorded;
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
const registerServerIdentityResource = (server, startedAt) => {
|
|
40
117
|
server.registerResource("server-identity", "rea://server/identity", {
|
|
41
118
|
title: "REA server identity",
|
|
42
119
|
description: "Live package, SDK, protocol, and catalog identity.",
|
|
43
120
|
mimeType: "application/json",
|
|
44
121
|
}, (uri) => {
|
|
45
122
|
const client = server.server.getClientVersion();
|
|
123
|
+
const protocolVersion = server.server.getNegotiatedProtocolVersion();
|
|
46
124
|
return {
|
|
47
125
|
contents: [
|
|
48
126
|
{
|
|
@@ -51,72 +129,49 @@ export const createServer = (analysis, session, options = {}) => {
|
|
|
51
129
|
text: JSON.stringify(createServerIdentity({
|
|
52
130
|
startedAt,
|
|
53
131
|
...(client === undefined ? {} : { client }),
|
|
54
|
-
...(
|
|
55
|
-
? {}
|
|
56
|
-
: {
|
|
57
|
-
protocolVersion: server.server.getNegotiatedProtocolVersion(),
|
|
58
|
-
}),
|
|
132
|
+
...(protocolVersion === undefined ? {} : { protocolVersion }),
|
|
59
133
|
}), null, 2),
|
|
60
134
|
},
|
|
61
135
|
],
|
|
62
136
|
};
|
|
63
137
|
});
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
? undefined
|
|
68
|
-
: (evidence) => {
|
|
69
|
-
const recorded = session.recordEvidence(evidence);
|
|
70
|
-
if (recorded.ok && recorded.value === "added")
|
|
71
|
-
server.sendResourceListChanged();
|
|
72
|
-
return recorded;
|
|
73
|
-
};
|
|
74
|
-
const recordEvidenceWithUnknown = session === undefined
|
|
138
|
+
};
|
|
139
|
+
const registerBinaryAnalysisTools = ({ server, analysis, session, options, logger, permissionAuthority, activeTarget, recordEvidence, recordEvidenceWithUnknown, }) => {
|
|
140
|
+
const recordUnknown = session === undefined
|
|
75
141
|
? undefined
|
|
76
|
-
: (
|
|
77
|
-
const recorded = session.recordEvidenceWithUnknown(evidence, input);
|
|
78
|
-
if (recorded.ok)
|
|
79
|
-
server.sendResourceListChanged();
|
|
80
|
-
return recorded;
|
|
81
|
-
};
|
|
142
|
+
: (input) => session.recordUnknown(input);
|
|
82
143
|
registerOfficialTools(server, analysis, {
|
|
83
|
-
logger
|
|
144
|
+
logger,
|
|
84
145
|
activeTarget,
|
|
85
146
|
recordEvidence,
|
|
86
|
-
recordUnknown
|
|
87
|
-
? undefined
|
|
88
|
-
: (input) => session.recordUnknown(input),
|
|
147
|
+
recordUnknown,
|
|
89
148
|
});
|
|
90
149
|
registerEnhancedTools(server, analysis, {
|
|
91
|
-
logger
|
|
150
|
+
logger,
|
|
92
151
|
activeTarget,
|
|
93
152
|
analysisProfile: session === undefined ? undefined : () => session.analysisProfile(),
|
|
94
153
|
recordEvidence,
|
|
95
|
-
recordUnknown
|
|
96
|
-
? undefined
|
|
97
|
-
: (input) => session.recordUnknown(input),
|
|
154
|
+
recordUnknown,
|
|
98
155
|
});
|
|
99
156
|
registerNativeTools(server, analysis, {
|
|
100
|
-
logger
|
|
157
|
+
logger,
|
|
101
158
|
activeTarget,
|
|
102
159
|
recordEvidence,
|
|
103
160
|
});
|
|
104
161
|
registerArtifactTools(server, analysis, {
|
|
105
|
-
logger
|
|
162
|
+
logger,
|
|
106
163
|
activeTarget,
|
|
107
164
|
recordEvidence,
|
|
108
|
-
...(
|
|
109
|
-
? {}
|
|
110
|
-
: { permissionAuthority: options.permissionAuthority }),
|
|
165
|
+
...(permissionAuthority === undefined ? {} : { permissionAuthority }),
|
|
111
166
|
});
|
|
112
167
|
registerManagedTools(server, analysis, {
|
|
113
|
-
logger
|
|
168
|
+
logger,
|
|
114
169
|
activeTarget,
|
|
115
170
|
recordEvidence,
|
|
116
171
|
});
|
|
117
172
|
if (session !== undefined)
|
|
118
173
|
registerManagedWorkflowTools(server, {
|
|
119
|
-
logger
|
|
174
|
+
logger,
|
|
120
175
|
recordEvidence,
|
|
121
176
|
recordEvidenceWithUnknown,
|
|
122
177
|
session,
|
|
@@ -126,25 +181,43 @@ export const createServer = (analysis, session, options = {}) => {
|
|
|
126
181
|
roots: [],
|
|
127
182
|
executablePath: "/usr/bin/dotnet",
|
|
128
183
|
},
|
|
129
|
-
authority:
|
|
184
|
+
authority: permissionAuthority,
|
|
130
185
|
},
|
|
131
186
|
});
|
|
187
|
+
};
|
|
188
|
+
const registerObservationTools = ({ server, session, options, logger, permissionAuthority, recordEvidence, recordEvidenceWithUnknown, }) => {
|
|
132
189
|
registerBrowserTools(server, {
|
|
133
|
-
logger
|
|
190
|
+
logger,
|
|
134
191
|
browser: options.browserObservation,
|
|
135
|
-
permissionAuthority
|
|
192
|
+
permissionAuthority,
|
|
136
193
|
recordEvidence,
|
|
137
194
|
});
|
|
138
195
|
registerElectronTools(server, {
|
|
139
|
-
logger
|
|
196
|
+
logger,
|
|
140
197
|
electron: options.electronObservation,
|
|
141
|
-
permissionAuthority
|
|
198
|
+
permissionAuthority,
|
|
142
199
|
recordEvidence,
|
|
143
200
|
});
|
|
144
201
|
registerApplicationTools(server, {
|
|
145
|
-
logger
|
|
202
|
+
logger,
|
|
146
203
|
recordEvidence,
|
|
147
204
|
recordEvidenceWithUnknown,
|
|
205
|
+
evidenceFilePolicy: options.evidenceFilePolicy ?? {
|
|
206
|
+
roots: [],
|
|
207
|
+
maxBytes: 1,
|
|
208
|
+
maxDepth: 1,
|
|
209
|
+
maxStringLength: 1,
|
|
210
|
+
maxNodes: 1,
|
|
211
|
+
},
|
|
212
|
+
permissionAuthority,
|
|
213
|
+
retainCoverageWorkspace: session === undefined
|
|
214
|
+
? undefined
|
|
215
|
+
: (workspace) => {
|
|
216
|
+
const retained = session.retainReconstructionCoverageWorkspace(workspace);
|
|
217
|
+
if (retained === "added")
|
|
218
|
+
server.sendResourceListChanged();
|
|
219
|
+
return retained;
|
|
220
|
+
},
|
|
148
221
|
replay: {
|
|
149
222
|
policy: options.javascriptReplayPolicy ?? {
|
|
150
223
|
enabled: false,
|
|
@@ -157,16 +230,8 @@ export const createServer = (analysis, session, options = {}) => {
|
|
|
157
230
|
},
|
|
158
231
|
host: options.javascriptReplayHost ?? new SystemJavaScriptReplayHost(),
|
|
159
232
|
runner: options.javascriptReplayRunner ?? new LinuxJavaScriptReplayRunner(),
|
|
160
|
-
authority:
|
|
233
|
+
authority: permissionAuthority,
|
|
161
234
|
},
|
|
162
235
|
});
|
|
163
|
-
registerGuidedPrompts(server, analysis, session);
|
|
164
|
-
if (session !== undefined) {
|
|
165
|
-
registerEvidenceResources(server, session);
|
|
166
|
-
registerSessionTools(server, session, toolLogger, {
|
|
167
|
-
...options,
|
|
168
|
-
startedAt,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
return server;
|
|
172
236
|
};
|
|
237
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { executeNodeCharacterization, prepareNodeCharacterization, } from "../../application/NodeRuntimeCharacterizationService.js";
|
|
2
|
+
import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
|
|
3
|
+
import { nodeCharacterizationExecutionInputSchema, nodeCharacterizationExecutionOutputSchema, nodeCharacterizationPreparationInputSchema, nodeCharacterizationPreparationOutputSchema, } from "../../domain/nodeRuntimeCharacterization.js";
|
|
4
|
+
import { parseEvidence } from "../../domain/evidence.js";
|
|
5
|
+
import { logToolExecution } from "../toolLogging.js";
|
|
6
|
+
import { toCallToolResult } from "../toolResult.js";
|
|
7
|
+
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
|
8
|
+
import { safeParseToolInput } from "../toolInputValidation.js";
|
|
9
|
+
import { mcpProgressReporter } from "../mcpProgress.js";
|
|
10
|
+
import { recordSources } from "./helpers.js";
|
|
11
|
+
const prepareContract = APPLICATION_TOOL_CONTRACTS[3];
|
|
12
|
+
const executeContract = APPLICATION_TOOL_CONTRACTS[4];
|
|
13
|
+
/** Register node runtime characterization prepare and execute tools. */
|
|
14
|
+
export const registerCharacterizationTools = (server, options) => {
|
|
15
|
+
server.registerTool(prepareContract.name, toolRegistrationOptions(prepareContract), async (input, context) => {
|
|
16
|
+
const parsed = safeParseToolInput(nodeCharacterizationPreparationInputSchema, input, prepareContract.name);
|
|
17
|
+
if (!parsed.ok)
|
|
18
|
+
return toCallToolResult(parsed, prepareContract);
|
|
19
|
+
const result = await logToolExecution(options.logger, prepareContract.name, () => prepareNodeCharacterization(options.replay, parsed.value, {
|
|
20
|
+
signal: context.mcpReq.signal,
|
|
21
|
+
progress: mcpProgressReporter(context),
|
|
22
|
+
}));
|
|
23
|
+
if (!result.ok)
|
|
24
|
+
return toCallToolResult(result, prepareContract);
|
|
25
|
+
const output = nodeCharacterizationPreparationOutputSchema.parse(result.value);
|
|
26
|
+
const recorded = options.recordEvidence?.(parseEvidence(output.transformation_evidence));
|
|
27
|
+
if (recorded !== undefined && !recorded.ok)
|
|
28
|
+
return toCallToolResult(recorded, prepareContract);
|
|
29
|
+
return toCallToolResult(result, prepareContract, {
|
|
30
|
+
evidenceResourcesAvailable: options.recordEvidence !== undefined,
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
server.registerTool(executeContract.name, toolRegistrationOptions(executeContract), async (input, context) => {
|
|
34
|
+
const parsed = safeParseToolInput(nodeCharacterizationExecutionInputSchema, input, executeContract.name);
|
|
35
|
+
if (!parsed.ok)
|
|
36
|
+
return toCallToolResult(parsed, executeContract);
|
|
37
|
+
const result = await logToolExecution(options.logger, executeContract.name, () => executeNodeCharacterization(options.replay, parsed.value, {
|
|
38
|
+
signal: context.mcpReq.signal,
|
|
39
|
+
progress: mcpProgressReporter(context),
|
|
40
|
+
}));
|
|
41
|
+
if (!result.ok)
|
|
42
|
+
return toCallToolResult(result, executeContract);
|
|
43
|
+
const output = nodeCharacterizationExecutionOutputSchema.parse(result.value);
|
|
44
|
+
const sources = [
|
|
45
|
+
output.transformation_evidence,
|
|
46
|
+
...output.replay.source_evidence,
|
|
47
|
+
...(output.replay.evidence === null ? [] : [output.replay.evidence]),
|
|
48
|
+
output.evidence,
|
|
49
|
+
].map((item) => parseEvidence(item));
|
|
50
|
+
const recorded = recordSources(options.recordEvidence, sources);
|
|
51
|
+
if (!recorded.ok)
|
|
52
|
+
return toCallToolResult(recorded, executeContract);
|
|
53
|
+
return toCallToolResult(result, executeContract, {
|
|
54
|
+
evidenceResourcesAvailable: options.recordEvidence !== undefined,
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { compareApplicationVersionsEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
|
|
2
|
+
import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
|
|
3
|
+
import { compareApplicationVersionsInputSchema } from "../../domain/javascriptApplicationVersionComparisonSchemas.js";
|
|
4
|
+
import { applicationVersionComparisonResultSchema } from "../../domain/javascriptApplicationVersionComparisonSchemas.js";
|
|
5
|
+
import { logToolExecution } from "../toolLogging.js";
|
|
6
|
+
import { toCallToolResult } from "../toolResult.js";
|
|
7
|
+
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
|
8
|
+
import { safeParseToolInput } from "../toolInputValidation.js";
|
|
9
|
+
import { recordResult, recordSources } from "./helpers.js";
|
|
10
|
+
const compareContract = APPLICATION_TOOL_CONTRACTS[1];
|
|
11
|
+
/** Register the provider-neutral JavaScript version comparison tool. */
|
|
12
|
+
export const registerCompareApplicationVersionsTool = (server, options) => {
|
|
13
|
+
server.registerTool(compareContract.name, toolRegistrationOptions(compareContract), async (input) => {
|
|
14
|
+
const parsedInput = safeParseToolInput(compareApplicationVersionsInputSchema, input, compareContract.name);
|
|
15
|
+
if (!parsedInput.ok)
|
|
16
|
+
return toCallToolResult(parsedInput, compareContract);
|
|
17
|
+
const parsed = parsedInput.value;
|
|
18
|
+
const result = await logToolExecution(options.logger, compareContract.name, () => Promise.resolve(compareApplicationVersionsEvidenceValidated(parsed)));
|
|
19
|
+
if (!result.ok)
|
|
20
|
+
return toCallToolResult(result, compareContract);
|
|
21
|
+
const sources = [
|
|
22
|
+
parsed.left,
|
|
23
|
+
parsed.right,
|
|
24
|
+
...parsed.left_native_observations,
|
|
25
|
+
...parsed.right_native_observations,
|
|
26
|
+
];
|
|
27
|
+
const recorded = recordSources(options.recordEvidence, sources);
|
|
28
|
+
if (!recorded.ok)
|
|
29
|
+
return toCallToolResult(recorded, compareContract);
|
|
30
|
+
const comparison = applicationVersionComparisonResultSchema.parse(result.value.normalized_result);
|
|
31
|
+
const unknown = comparison.summary.unknown > 0;
|
|
32
|
+
return recordResult(options, compareContract, result.value, parsed.unknown_registry_approved === true && unknown);
|
|
33
|
+
});
|
|
34
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { runControlledReplayValidated } from "../../application/JavaScriptReplayService.js";
|
|
2
|
+
import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
|
|
3
|
+
import { controlledReplayInputSchema, controlledReplayOutputSchema, } from "../../domain/javascriptReplay.js";
|
|
4
|
+
import { parseEvidence } from "../../domain/evidence.js";
|
|
5
|
+
import { logToolExecution } from "../toolLogging.js";
|
|
6
|
+
import { toCallToolResult } from "../toolResult.js";
|
|
7
|
+
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
|
8
|
+
import { safeParseToolInput } from "../toolInputValidation.js";
|
|
9
|
+
import { mcpProgressReporter } from "../mcpProgress.js";
|
|
10
|
+
import { recordSources } from "./helpers.js";
|
|
11
|
+
const replayContract = APPLICATION_TOOL_CONTRACTS[2];
|
|
12
|
+
/** Register the controlled JavaScript replay tool. */
|
|
13
|
+
export const registerControlledReplayTool = (server, options) => {
|
|
14
|
+
server.registerTool(replayContract.name, toolRegistrationOptions(replayContract), async (input, context) => {
|
|
15
|
+
const parsedInput = safeParseToolInput(controlledReplayInputSchema, input, replayContract.name);
|
|
16
|
+
if (!parsedInput.ok)
|
|
17
|
+
return toCallToolResult(parsedInput, replayContract);
|
|
18
|
+
const parsed = parsedInput.value;
|
|
19
|
+
const result = await logToolExecution(options.logger, replayContract.name, () => runControlledReplayValidated(options.replay, parsed, {
|
|
20
|
+
signal: context.mcpReq.signal,
|
|
21
|
+
progress: mcpProgressReporter(context),
|
|
22
|
+
}));
|
|
23
|
+
if (!result.ok)
|
|
24
|
+
return toCallToolResult(result, replayContract);
|
|
25
|
+
const output = controlledReplayOutputSchema.parse(result.value);
|
|
26
|
+
if (output.evidence !== null) {
|
|
27
|
+
const sourcesRecorded = recordSources(options.recordEvidence, output.source_evidence.map((item) => parseEvidence(item)));
|
|
28
|
+
if (!sourcesRecorded.ok)
|
|
29
|
+
return toCallToolResult(sourcesRecorded, replayContract);
|
|
30
|
+
const recorded = options.recordEvidence?.(parseEvidence(output.evidence));
|
|
31
|
+
if (recorded !== undefined && !recorded.ok)
|
|
32
|
+
return toCallToolResult(recorded, replayContract);
|
|
33
|
+
}
|
|
34
|
+
return toCallToolResult(result, replayContract, {
|
|
35
|
+
evidenceResourcesAvailable: output.evidence !== null && options.recordEvidence !== undefined,
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { commitReconstructionCoverage, queryReconstructionCoverage, } from "../../application/ReconstructionCoverageService.js";
|
|
2
|
+
import { readReconstructionCoverageWorkspace } from "../../application/ReconstructionCoverageWorkspaceStore.js";
|
|
3
|
+
import { authorizeFileReadWithDeferredWrite, authorizeRootPermission, } from "../../application/DeferredFileAuthorization.js";
|
|
4
|
+
import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
|
|
5
|
+
import { reconstructionCoverageCommitInputSchema, reconstructionCoverageQueryInputSchema, } from "../../application/ReconstructionCoverageService.js";
|
|
6
|
+
import { reconstructionClosureResultSchema } from "../../domain/reconstructionCoverage.js";
|
|
7
|
+
import { AnalysisCapabilityUnavailableError, EvidenceIntegrityError, } from "../../domain/errors.js";
|
|
8
|
+
import { err } from "../../domain/result.js";
|
|
9
|
+
import { logToolExecution } from "../toolLogging.js";
|
|
10
|
+
import { toCallToolResult } from "../toolResult.js";
|
|
11
|
+
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
|
12
|
+
import { safeParseToolInput } from "../toolInputValidation.js";
|
|
13
|
+
import { coverageWorkspaceUri } from "./helpers.js";
|
|
14
|
+
const commitContract = APPLICATION_TOOL_CONTRACTS[5];
|
|
15
|
+
const queryContract = APPLICATION_TOOL_CONTRACTS[6];
|
|
16
|
+
/** Register reconstruction coverage commit and query tools. */
|
|
17
|
+
export const registerCoverageTools = (server, options) => {
|
|
18
|
+
registerCommitTool(server, options);
|
|
19
|
+
registerQueryTool(server, options);
|
|
20
|
+
};
|
|
21
|
+
const registerCommitTool = (server, options) => {
|
|
22
|
+
server.registerTool(commitContract.name, toolRegistrationOptions(commitContract), async (input, context) => {
|
|
23
|
+
const parsed = safeParseToolInput(reconstructionCoverageCommitInputSchema, input, commitContract.name);
|
|
24
|
+
if (!parsed.ok)
|
|
25
|
+
return toCallToolResult(parsed, commitContract);
|
|
26
|
+
if (options.permissionAuthority === undefined)
|
|
27
|
+
return toCallToolResult(err(new AnalysisCapabilityUnavailableError("rea-reconstruction-coverage", commitContract.name, "workspace permission policy is not configured")), commitContract);
|
|
28
|
+
const authorization = await authorizeFileReadWithDeferredWrite(options.permissionAuthority, {
|
|
29
|
+
path: parsed.value.workspace_path,
|
|
30
|
+
readCapability: "investigation_workspace_read",
|
|
31
|
+
writeCapability: "investigation_workspace_write",
|
|
32
|
+
operation: commitContract.name,
|
|
33
|
+
});
|
|
34
|
+
if (!authorization.ok)
|
|
35
|
+
return toCallToolResult(authorization, commitContract);
|
|
36
|
+
const write = await authorization.value.authorizeWrite();
|
|
37
|
+
if (!write.ok)
|
|
38
|
+
return toCallToolResult(write, commitContract);
|
|
39
|
+
const result = await logToolExecution(options.logger, commitContract.name, () => commitReconstructionCoverage(parsed.value, options.evidenceFilePolicy, { signal: context.mcpReq.signal }));
|
|
40
|
+
if (!result.ok)
|
|
41
|
+
return toCallToolResult(result, commitContract);
|
|
42
|
+
options.retainCoverageWorkspace?.(parsed.value.workspace);
|
|
43
|
+
return toCallToolResult(result, commitContract, {
|
|
44
|
+
resourceLinks: options.retainCoverageWorkspace === undefined
|
|
45
|
+
? []
|
|
46
|
+
: [
|
|
47
|
+
{
|
|
48
|
+
uri: coverageWorkspaceUri(parsed.value.workspace),
|
|
49
|
+
name: parsed.value.workspace.workspace_id,
|
|
50
|
+
description: "Session-retained reconstruction coverage workspace revision",
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
const registerQueryTool = (server, options) => {
|
|
57
|
+
server.registerTool(queryContract.name, toolRegistrationOptions(queryContract), async (input, context) => {
|
|
58
|
+
const parsed = safeParseToolInput(reconstructionCoverageQueryInputSchema, input, queryContract.name);
|
|
59
|
+
if (!parsed.ok)
|
|
60
|
+
return toCallToolResult(parsed, queryContract);
|
|
61
|
+
if (options.permissionAuthority === undefined)
|
|
62
|
+
return toCallToolResult(err(new AnalysisCapabilityUnavailableError("rea-reconstruction-coverage", queryContract.name, "workspace permission policy is not configured")), queryContract);
|
|
63
|
+
const authorized = await authorizeRootPermission(options.permissionAuthority, {
|
|
64
|
+
capability: "investigation_workspace_read",
|
|
65
|
+
roots: [parsed.value.workspace_path],
|
|
66
|
+
access: "read",
|
|
67
|
+
operation: queryContract.name,
|
|
68
|
+
});
|
|
69
|
+
if (!authorized.ok)
|
|
70
|
+
return toCallToolResult(authorized, queryContract);
|
|
71
|
+
const result = await logToolExecution(options.logger, queryContract.name, () => queryReconstructionCoverage(parsed.value, options.evidenceFilePolicy, Date.now(), { signal: context.mcpReq.signal }));
|
|
72
|
+
if (result.ok && options.retainCoverageWorkspace !== undefined) {
|
|
73
|
+
const closure = reconstructionClosureResultSchema.parse(result.value);
|
|
74
|
+
const loaded = await readReconstructionCoverageWorkspace(parsed.value.workspace_path, options.evidenceFilePolicy);
|
|
75
|
+
if (!loaded.ok)
|
|
76
|
+
return toCallToolResult(loaded, queryContract);
|
|
77
|
+
if (loaded.value === null ||
|
|
78
|
+
loaded.value.revision_sha256 !== closure.workspace_revision_sha256)
|
|
79
|
+
return toCallToolResult(err(new EvidenceIntegrityError("workspace changed while its closure was being retained")), queryContract);
|
|
80
|
+
options.retainCoverageWorkspace(loaded.value);
|
|
81
|
+
}
|
|
82
|
+
return toCallToolResult(result, queryContract);
|
|
83
|
+
});
|
|
84
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
|
|
2
|
+
import { toCallToolResult } from "../toolResult.js";
|
|
3
|
+
export const coverageWorkspaceUri = (workspace) => `rea://reconstruction-coverage/${workspace.workspace_id}/revision/${String(workspace.revision)}`;
|
|
4
|
+
export const recordSources = (recordEvidence, sources) => {
|
|
5
|
+
for (const source of sources) {
|
|
6
|
+
const recorded = recordEvidence?.(source);
|
|
7
|
+
if (recorded !== undefined && !recorded.ok)
|
|
8
|
+
return recorded;
|
|
9
|
+
}
|
|
10
|
+
return { ok: true, value: null };
|
|
11
|
+
};
|
|
12
|
+
export const recordResult = (options, contract, evidence, recordUnknown = false) => {
|
|
13
|
+
const recorded = recordUnknown
|
|
14
|
+
? options.recordEvidenceWithUnknown?.(evidence, {
|
|
15
|
+
approved: true,
|
|
16
|
+
question: "Which application entities remain unmatched or ambiguous across these versions?",
|
|
17
|
+
severity: "medium",
|
|
18
|
+
domain: "application-version-comparison",
|
|
19
|
+
supporting_evidence_ids: [evidence.evidence_id],
|
|
20
|
+
contradicting_evidence_ids: [],
|
|
21
|
+
required_authority: "shipped-artifact",
|
|
22
|
+
required_confidence: "observed",
|
|
23
|
+
required_environment: null,
|
|
24
|
+
recommended_probes: [
|
|
25
|
+
{
|
|
26
|
+
operation: "analyze_javascript_application",
|
|
27
|
+
rationale: "Repeat static reconstruction with complete artifacts and source maps when available.",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
operation: "reconcile_javascript_runtime",
|
|
31
|
+
rationale: "Add approved passive runtime Evidence without promoting it to static fact.",
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
relationships: [],
|
|
35
|
+
})
|
|
36
|
+
: options.recordEvidence?.(evidence);
|
|
37
|
+
if (recorded !== undefined && !recorded.ok)
|
|
38
|
+
return toCallToolResult(recorded, contract);
|
|
39
|
+
return toCallToolResult({ ok: true, value: evidence }, contract, {
|
|
40
|
+
evidenceResourcesAvailable: recorded !== undefined,
|
|
41
|
+
});
|
|
42
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { traceApplicationFeatureEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
|
|
2
|
+
import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
|
|
3
|
+
import { traceApplicationFeatureInputSchema } from "../../domain/javascriptFeatureTraceSchemas.js";
|
|
4
|
+
import { logToolExecution } from "../toolLogging.js";
|
|
5
|
+
import { toCallToolResult } from "../toolResult.js";
|
|
6
|
+
import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
|
|
7
|
+
import { safeParseToolInput } from "../toolInputValidation.js";
|
|
8
|
+
import { recordResult, recordSources } from "./helpers.js";
|
|
9
|
+
const traceContract = APPLICATION_TOOL_CONTRACTS[0];
|
|
10
|
+
/** Register the provider-neutral JavaScript feature trace tool. */
|
|
11
|
+
export const registerTraceFeatureTool = (server, options) => {
|
|
12
|
+
server.registerTool(traceContract.name, toolRegistrationOptions(traceContract), async (input) => {
|
|
13
|
+
const parsedInput = safeParseToolInput(traceApplicationFeatureInputSchema, input, traceContract.name);
|
|
14
|
+
if (!parsedInput.ok)
|
|
15
|
+
return toCallToolResult(parsedInput, traceContract);
|
|
16
|
+
const parsed = parsedInput.value;
|
|
17
|
+
const result = await logToolExecution(options.logger, traceContract.name, () => Promise.resolve(traceApplicationFeatureEvidenceValidated(parsed)));
|
|
18
|
+
if (!result.ok)
|
|
19
|
+
return toCallToolResult(result, traceContract);
|
|
20
|
+
const sources = [parsed.application, ...parsed.native_observations];
|
|
21
|
+
const recorded = recordSources(options.recordEvidence, sources);
|
|
22
|
+
if (!recorded.ok)
|
|
23
|
+
return toCallToolResult(recorded, traceContract);
|
|
24
|
+
return recordResult(options, traceContract, result.value);
|
|
25
|
+
});
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|