rea-agents 2.1.0 → 2.3.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 +84 -18
- package/dist/application/AndroidApplicationService.js +17 -0
- package/dist/application/AppleApplicationService.js +17 -0
- package/dist/application/ApplicationWorkflowEvidenceResolver.js +162 -0
- package/dist/application/BinarySession.js +9 -2
- package/dist/application/BinarySessionStatus.js +39 -1
- package/dist/application/CapabilityInventory.js +15 -0
- package/dist/application/ClientRegistrationStatus.js +11 -4
- package/dist/application/CommandShimReplay.js +6 -3
- package/dist/application/CompositeProvider.js +5 -2
- package/dist/application/DirectAnalysis.js +1 -20
- package/dist/application/DirectAnalysisStatus.js +83 -0
- package/dist/application/Doctor.js +34 -25
- package/dist/application/DoctorDiagnostics.js +1 -4
- package/dist/application/DoctorProjection.js +43 -0
- package/dist/application/DoctorScope.js +102 -0
- package/dist/application/EvidenceReferenceResolver.js +26 -0
- package/dist/application/InventoryProjectionEvidence.js +41 -0
- package/dist/application/InvestigationProviders.js +12 -0
- package/dist/application/JavaScriptApplicationEvidence.js +1 -1
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +10 -1
- package/dist/application/JavaScriptApplicationService.js +3 -2
- package/dist/application/JavaScriptApplicationWorkflowEvidence.js +26 -0
- package/dist/application/JavaScriptApplicationWorkflowService.js +49 -1
- package/dist/application/JavaScriptArtifactReconstruction.js +7 -0
- package/dist/application/JavaScriptModuleRelationships.js +25 -1
- package/dist/application/JavaScriptReturnShapeProjection.js +111 -0
- package/dist/application/JavaScriptSemanticGraphBuilder.js +294 -0
- package/dist/application/JavaScriptSemanticGraphConstruction.js +144 -0
- package/dist/application/JavaScriptSemanticGraphEvidence.js +86 -0
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +72 -0
- package/dist/application/JavaScriptSemanticGraphProjection.js +33 -0
- package/dist/application/JavaScriptSemanticTraceService.js +45 -0
- package/dist/application/LoopbackReplay.js +277 -133
- package/dist/application/LoopbackReplayRecorder.js +101 -0
- package/dist/application/PermissionAuthority.js +7 -3
- package/dist/application/ProcessCaptureJournal.js +95 -0
- package/dist/application/ProcessCaptureLifecycle.js +24 -13
- package/dist/application/ProcessCheckpoints.js +30 -4
- package/dist/application/ProcessCli.js +26 -4
- package/dist/application/ProcessHarness.js +20 -50
- package/dist/application/ProcessNormalization.js +3 -2
- package/dist/application/ProcessPairedExperiment.js +72 -0
- package/dist/application/ProcessReactiveCoordinator.js +218 -0
- package/dist/application/ProcessReactiveEffects.js +133 -0
- package/dist/application/ProcessReactiveObservations.js +20 -0
- package/dist/application/ProcessSampling.js +2 -0
- package/dist/application/SessionProviderRouter.js +7 -6
- package/dist/application/Setup.js +14 -13
- package/dist/application/SetupClientConfiguration.js +10 -6
- package/dist/application/SetupPlan.js +4 -3
- package/dist/application/SetupRegistrationEnvironment.js +12 -0
- package/dist/application/SetupSkill.js +44 -40
- package/dist/application/TerminalRenderer.js +3 -1
- package/dist/application/Uninstall.js +7 -1
- package/dist/application/Upgrade.js +16 -1
- package/dist/browser/CdpEndpoint.js +37 -4
- package/dist/catalogIdentity.js +16 -7
- package/dist/cli/coreAnalysisCommands.js +34 -2
- package/dist/cli/javascriptApplicationAnalysis.js +19 -0
- package/dist/cli/setupCommands.js +84 -30
- package/dist/cli/utilityCommands.js +10 -2
- package/dist/cliApplicationCommands.js +79 -16
- package/dist/cliCommandNames.js +3 -0
- package/dist/cliElectronCommands.js +23 -33
- package/dist/cliObservationOptions.js +1 -1
- package/dist/cliOutput.js +56 -0
- package/dist/cliProcessCommands.js +32 -1
- package/dist/cliSetup.js +55 -29
- package/dist/contracts/applicationToolContracts.js +54 -7
- package/dist/contracts/applicationWorkflowInputContracts.js +119 -0
- package/dist/contracts/electronToolContracts.js +73 -4
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +32 -9
- package/dist/contracts/managedToolContracts.js +7 -2
- package/dist/contracts/processCaptureExample.js +1 -0
- package/dist/contracts/replayMachineExample.js +37 -0
- package/dist/contracts/sessionStatusContract.js +26 -0
- package/dist/contracts/toolContractExamples.js +2 -0
- package/dist/contracts/toolContractTypes.js +12 -1
- package/dist/contracts/toolContracts.js +8 -11
- package/dist/contracts/toolEffects.js +3 -0
- package/dist/contracts/toolOutputSchemaGroups.js +53 -9
- package/dist/contracts/toolOutputSchemaPrimitives.js +73 -32
- package/dist/doctorRuntime.js +41 -0
- package/dist/domain/analysisErrorPresentation.js +5 -3
- package/dist/domain/analysisErrorProjection.js +7 -1
- package/dist/domain/androidApplication.js +206 -0
- package/dist/domain/appleApplication.js +221 -0
- package/dist/domain/boundedCartesianProjection.js +15 -0
- package/dist/domain/changedBehavior.js +5 -4
- package/dist/domain/completionLedgerGeneration.js +190 -0
- package/dist/domain/errors.js +4 -2
- package/dist/domain/evidenceCompletionLedger.js +113 -0
- package/dist/domain/hopperStartupFailure.js +9 -0
- package/dist/domain/javascriptApplicationAnalysis.js +44 -2
- package/dist/domain/javascriptExportShapeComparison.js +145 -0
- package/dist/domain/javascriptExportShapeComparisonIdentity.js +11 -0
- package/dist/domain/javascriptExportShapeComparisonSchemas.js +277 -0
- package/dist/domain/javascriptExportShapeSelection.js +132 -0
- package/dist/domain/javascriptExportShapeVariants.js +272 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +2 -2
- package/dist/domain/javascriptSemanticAnalysis.js +17 -36
- package/dist/domain/javascriptSemanticCallResolution.js +129 -0
- package/dist/domain/javascriptSemanticCalls.js +269 -0
- package/dist/domain/javascriptSemanticGraph.js +356 -0
- package/dist/domain/javascriptSemanticGraphSchemas.js +329 -0
- package/dist/domain/javascriptSemanticGraphSerialization.js +23 -0
- package/dist/domain/javascriptSemanticIr.js +14 -1
- package/dist/domain/javascriptSemanticPrimitives.js +36 -0
- package/dist/domain/javascriptSemanticProjection.js +36 -4
- package/dist/domain/javascriptSemanticProvenance.js +29 -0
- package/dist/domain/javascriptSemanticQuery.js +294 -0
- package/dist/domain/javascriptSemanticQueryAssessment.js +74 -0
- package/dist/domain/javascriptSemanticQueryIdentity.js +86 -0
- package/dist/domain/javascriptSemanticQueryRelations.js +15 -0
- package/dist/domain/javascriptSemanticQuerySchemas.js +188 -0
- package/dist/domain/javascriptSemanticReturns.js +187 -0
- package/dist/domain/javascriptSemanticState.js +32 -0
- package/dist/domain/javascriptSemanticTraceSchemas.js +14 -0
- package/dist/domain/javascriptSemanticValues.js +54 -70
- package/dist/domain/processCapture.js +36 -0
- package/dist/domain/processCaptureValidation.js +101 -12
- package/dist/domain/processComparison.js +96 -24
- package/dist/domain/processObservation.js +153 -0
- package/dist/domain/processPairedExperiment.js +128 -0
- package/dist/domain/processReactiveCheckpointDataflow.js +32 -0
- package/dist/domain/processReactiveMatching.js +210 -0
- package/dist/domain/processReactiveRuntime.js +109 -0
- package/dist/domain/processReactiveScenario.js +361 -0
- package/dist/domain/processReactiveScenarioPreflight.js +120 -0
- package/dist/domain/processReactiveTransition.js +159 -0
- package/dist/domain/processScenario.js +12 -0
- package/dist/domain/processTraceComparison.js +43 -0
- package/dist/domain/processTraceDimensionProjection.js +50 -0
- package/dist/domain/processTraceEvaluation.js +312 -0
- package/dist/domain/processTraceSpecification.js +373 -0
- package/dist/domain/reconstructionVerification.js +5 -4
- package/dist/domain/replayMachine.js +332 -0
- package/dist/domain/replayMachineRun.js +216 -0
- package/dist/domain/replayMachineRuntime.js +294 -0
- package/dist/domain/runtimeIdentification.js +210 -0
- package/dist/domain/staticRuntimeCorrelation.js +4 -2
- package/dist/evaluation/CodexAgentEval.js +156 -0
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraClient.js +13 -2
- package/dist/ghidra/GhidraDiagnostics.js +1 -0
- package/dist/ghidra/GhidraLauncher.js +7 -3
- package/dist/ghidra/GhidraProvider.js +8 -1
- package/dist/hopper/BridgeLauncher.js +56 -14
- package/dist/hopper/HopperClient.js +23 -10
- package/dist/hopper/HopperDiagnostics.js +14 -0
- package/dist/hopper/HopperProcessDiagnostic.js +14 -0
- package/dist/hopper/HopperProvider.js +8 -1
- package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +72 -0
- package/dist/hopper/LinuxPrivateDisplayProbe.js +217 -0
- package/dist/identity.js +2 -1
- package/dist/main/transport.js +2 -0
- package/dist/mcpDoctor.js +310 -0
- package/dist/process/ProcessOwnership.js +200 -53
- package/dist/process/ProviderRunLineage.js +21 -0
- package/dist/server/createServer.js +8 -2
- package/dist/server/javascriptApplicationResult.js +106 -0
- package/dist/server/registerApplicationTools/characterization.js +3 -3
- package/dist/server/registerApplicationTools/compareExportShapes.js +37 -0
- package/dist/server/registerApplicationTools/compareVersions.js +12 -6
- package/dist/server/registerApplicationTools/controlledReplay.js +2 -2
- package/dist/server/registerApplicationTools/coverage.js +3 -3
- package/dist/server/registerApplicationTools/helpers.js +37 -25
- package/dist/server/registerApplicationTools/traceFeature.js +9 -5
- package/dist/server/registerApplicationTools/traceSemantics.js +30 -0
- package/dist/server/registerApplicationTools.js +4 -0
- package/dist/server/registerElectronTools.js +19 -5
- package/dist/server/registerEvidenceResources.js +7 -1
- package/dist/server/registerJavaScriptApplicationGraphResource.js +69 -0
- package/dist/server/registerManagedTools.js +18 -1
- package/dist/server/registerProcessComparisonTool.js +17 -7
- package/dist/server/registerReplayMachineTool.js +20 -0
- package/dist/server/registerSessionStatusTool.js +95 -25
- package/dist/server/registerSessionTools.js +12 -7
- package/dist/server/sessionAvailabilityPolicy.js +2 -1
- package/dist/server/toolResult.js +10 -4
- package/dist/serverIdentity.js +19 -0
- package/package.json +62 -29
- package/scripts/hopper-demo-x11.py +459 -61
- package/scripts/prepack.mjs +55 -0
- package/scripts/prepare.mjs +28 -0
- package/scripts/rea.mjs +26 -5
- package/skills/reverse-engineer-anything/SKILL.md +69 -228
- package/skills/reverse-engineer-anything/references/controlled-replay.md +12 -0
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +33 -0
- package/skills/reverse-engineer-anything/references/javascript-applications.md +35 -0
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +36 -0
- package/skills/reverse-engineer-anything/references/runtime-observation.md +24 -0
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { parseConfig } from "../config.js";
|
|
2
|
-
import { jsonObjectSchema } from "../domain/jsonValue.js";
|
|
3
|
-
import { createServerIdentity } from "../serverIdentity.js";
|
|
4
2
|
import { EnhancedTools } from "./EnhancedTools.js";
|
|
5
3
|
import { createBinarySession } from "./runtime.js";
|
|
6
4
|
import { silentLogger } from "../logger.js";
|
|
@@ -14,6 +12,7 @@ import { err, ok } from "../domain/result.js";
|
|
|
14
12
|
import { loadConfiguredPermissionAuthority } from "./PermissionConfiguration.js";
|
|
15
13
|
import { authorizeFileReadWithDeferredWrite, } from "./DeferredFileAuthorization.js";
|
|
16
14
|
import { REA_WORKFLOW_PROVIDER, workflowAnalysisProfile, } from "./InvestigationProviders.js";
|
|
15
|
+
export { runCapabilityStatus, runProviderStatus, } from "./DirectAnalysisStatus.js";
|
|
17
16
|
/**
|
|
18
17
|
* Open one binary, execute one tool, and always release provider resources.
|
|
19
18
|
* Unlike MCP mode, every CLI invocation is intentionally isolated and does not
|
|
@@ -36,24 +35,6 @@ export const runProviderAnalysis = async (...[path, tool, arguments_, logger = s
|
|
|
36
35
|
snapshotPath: undefined,
|
|
37
36
|
signal: operationSignal,
|
|
38
37
|
}));
|
|
39
|
-
/** Describe configured providers without opening a target or starting one. */
|
|
40
|
-
export const runSessionStatus = async (logger = silentLogger) => {
|
|
41
|
-
const config = parseConfig(process.env);
|
|
42
|
-
if (!config.ok)
|
|
43
|
-
return cliError(config.error);
|
|
44
|
-
const session = createBinarySession(config.value, logger);
|
|
45
|
-
try {
|
|
46
|
-
return {
|
|
47
|
-
...jsonObjectSchema.parse(session.status()),
|
|
48
|
-
server_identity: createServerIdentity({
|
|
49
|
-
startedAt: new Date().toISOString(),
|
|
50
|
-
}),
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
finally {
|
|
54
|
-
await session.close();
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
38
|
const authorizeAnalysis = async (authority, tool, arguments_) => {
|
|
58
39
|
const requests = [];
|
|
59
40
|
if (tool === "extract_artifact" && typeof arguments_.output_root === "string")
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { parseConfig } from "../config.js";
|
|
2
|
+
import { projectAnalysisError } from "../domain/errors.js";
|
|
3
|
+
import { jsonObjectSchema } from "../domain/jsonValue.js";
|
|
4
|
+
import { createServerIdentity, createServerIdentitySummary, } from "../serverIdentity.js";
|
|
5
|
+
import { silentLogger } from "../logger.js";
|
|
6
|
+
import { createBinarySession } from "./runtime.js";
|
|
7
|
+
const runSessionStatus = async (logger = silentLogger) => {
|
|
8
|
+
const config = parseConfig(process.env);
|
|
9
|
+
if (!config.ok)
|
|
10
|
+
return { error: projectAnalysisError(config.error) };
|
|
11
|
+
const session = createBinarySession(config.value, logger);
|
|
12
|
+
try {
|
|
13
|
+
return {
|
|
14
|
+
...jsonObjectSchema.parse(session.status()),
|
|
15
|
+
server_identity: createServerIdentity({
|
|
16
|
+
startedAt: new Date().toISOString(),
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
await session.close();
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
/** List provider identities, selection, and availability without capability bodies. */
|
|
25
|
+
export const runProviderStatus = async (logger = silentLogger, detail = "summary") => {
|
|
26
|
+
const fullStatus = await runSessionStatus(logger);
|
|
27
|
+
if (detail === "full")
|
|
28
|
+
return fullStatus;
|
|
29
|
+
const parsedStatus = jsonObjectSchema.safeParse(fullStatus);
|
|
30
|
+
if (!parsedStatus.success || parsedStatus.data.error !== undefined)
|
|
31
|
+
return fullStatus;
|
|
32
|
+
const status = parsedStatus.data;
|
|
33
|
+
return {
|
|
34
|
+
open: status.open ?? false,
|
|
35
|
+
provider: status.provider ?? null,
|
|
36
|
+
providers: status.providers ?? [],
|
|
37
|
+
analysis_provider_binding: status.analysis_provider_binding ?? null,
|
|
38
|
+
analysis_provider_candidates: projectJsonObjectArray(status.analysis_provider_candidates, ["provider", "availability", "target_support", "selected"]),
|
|
39
|
+
server_identity: createServerIdentitySummary({
|
|
40
|
+
startedAt: new Date().toISOString(),
|
|
41
|
+
}),
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
/** List concise operation availability, with explicit full descriptor opt-in. */
|
|
45
|
+
export const runCapabilityStatus = async (logger = silentLogger, detail = "summary") => {
|
|
46
|
+
const fullStatus = await runSessionStatus(logger);
|
|
47
|
+
if (detail === "full")
|
|
48
|
+
return fullStatus;
|
|
49
|
+
const parsedStatus = jsonObjectSchema.safeParse(fullStatus);
|
|
50
|
+
if (!parsedStatus.success || parsedStatus.data.error !== undefined)
|
|
51
|
+
return fullStatus;
|
|
52
|
+
const status = parsedStatus.data;
|
|
53
|
+
const capabilities = projectJsonObjectArray(status.capabilities, [
|
|
54
|
+
"operation",
|
|
55
|
+
"available",
|
|
56
|
+
"reason",
|
|
57
|
+
]);
|
|
58
|
+
const available = capabilities.filter((candidate) => typeof candidate === "object" &&
|
|
59
|
+
candidate !== null &&
|
|
60
|
+
"available" in candidate &&
|
|
61
|
+
candidate.available === true).length;
|
|
62
|
+
return {
|
|
63
|
+
open: status.open ?? false,
|
|
64
|
+
summary: {
|
|
65
|
+
total: capabilities.length,
|
|
66
|
+
available,
|
|
67
|
+
unavailable: capabilities.length - available,
|
|
68
|
+
},
|
|
69
|
+
capabilities,
|
|
70
|
+
analysis_provider_binding: status.analysis_provider_binding ?? null,
|
|
71
|
+
server_identity: createServerIdentitySummary({
|
|
72
|
+
startedAt: new Date().toISOString(),
|
|
73
|
+
}),
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
const projectJsonObjectArray = (value, keys) => Array.isArray(value)
|
|
77
|
+
? value.map((candidate) => {
|
|
78
|
+
const parsed = jsonObjectSchema.safeParse(candidate);
|
|
79
|
+
if (!parsed.success)
|
|
80
|
+
return candidate;
|
|
81
|
+
return Object.fromEntries(keys.flatMap((key) => parsed.data[key] === undefined ? [] : [[key, parsed.data[key]]]));
|
|
82
|
+
})
|
|
83
|
+
: [];
|
|
@@ -12,25 +12,42 @@ import { PRODUCT_IDENTITY, SDK_IDENTITY } from "../identity.js";
|
|
|
12
12
|
import { readClientRegistrationStatuses, } from "./ClientRegistrationStatus.js";
|
|
13
13
|
import { inspectRuntimeExecutables, } from "./RuntimeExecutableDiagnostics.js";
|
|
14
14
|
import { collectDoctorDiagnostics, doctorHealthy, } from "./DoctorDiagnostics.js";
|
|
15
|
+
import { normalizeDoctorScope, scopeDoctorChecks, } from "./DoctorScope.js";
|
|
15
16
|
const execFileAsync = promisify(execFile);
|
|
17
|
+
/** Deep provider IDs whose readiness can be selected explicitly by doctor. */
|
|
18
|
+
export const DOCTOR_PROVIDER_IDS = ["hopper", "ghidra"];
|
|
16
19
|
/**
|
|
17
20
|
* Check requirements and an optional target without mutating the host.
|
|
18
21
|
* Every failed check includes remediation suitable for either the one-shot CLI
|
|
19
22
|
* or an agent consuming the structured result.
|
|
20
23
|
*/
|
|
21
|
-
export const runDoctor = async (target, host = systemDoctorHost()) => {
|
|
24
|
+
export const runDoctor = async (target, host = systemDoctorHost(), requestedScope) => {
|
|
22
25
|
const { checks: diagnosticChecks, hopperPath, providerInspections, runtimeExecutables, } = await collectDoctorDiagnostics(target, host);
|
|
23
26
|
const identity = await collectDoctorIdentity(host, runtimeExecutables);
|
|
24
27
|
const checks = [...diagnosticChecks, ...identity.checks];
|
|
28
|
+
const providers = {
|
|
29
|
+
hopperAvailable: hopperPath !== undefined &&
|
|
30
|
+
checks
|
|
31
|
+
.filter(({ name }) => name.startsWith("hopper"))
|
|
32
|
+
.every(({ ok }) => ok),
|
|
33
|
+
hopperConfigured: host.configuredHopperPath !== undefined,
|
|
34
|
+
providerInspections,
|
|
35
|
+
};
|
|
36
|
+
const environmentHealthy = doctorHealthy(checks, providers);
|
|
37
|
+
const scope = normalizeDoctorScope(requestedScope, target);
|
|
38
|
+
const scoped = scopeDoctorChecks({
|
|
39
|
+
checks,
|
|
40
|
+
registrations: identity.value.registrations,
|
|
41
|
+
skillState: identity.value.skill.state,
|
|
42
|
+
providers,
|
|
43
|
+
scope,
|
|
44
|
+
});
|
|
25
45
|
return {
|
|
26
|
-
healthy:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
hopperConfigured: host.configuredHopperPath !== undefined,
|
|
32
|
-
providerInspections,
|
|
33
|
-
}),
|
|
46
|
+
healthy: scope.mode === "audit-wide" ? environmentHealthy : scoped.healthy,
|
|
47
|
+
environment_healthy: environmentHealthy,
|
|
48
|
+
scope,
|
|
49
|
+
scope_checks: scope.mode === "audit-wide" ? checks : scoped.scopeChecks,
|
|
50
|
+
informational_checks: scope.mode === "audit-wide" ? [] : scoped.informationalChecks,
|
|
34
51
|
...(hopperPath === undefined ? {} : { hopperPath }),
|
|
35
52
|
...(providerInspections === undefined ? {} : { providerInspections }),
|
|
36
53
|
checks,
|
|
@@ -127,7 +144,7 @@ export const systemDoctorHost = (options = {}) => ({
|
|
|
127
144
|
return (await parseBinaryTarget(path)).ok;
|
|
128
145
|
},
|
|
129
146
|
executable: executableAvailable,
|
|
130
|
-
|
|
147
|
+
linuxDemoRuntimeCheck: options.linuxDemoRuntimeCheck ?? uncomposedLinuxDemoRuntimeCheck,
|
|
131
148
|
supportedLinuxHopper: linuxHopperBinarySupported,
|
|
132
149
|
async brewHopperPath() {
|
|
133
150
|
return probeHomebrew(async (command) => {
|
|
@@ -202,21 +219,13 @@ const executableAvailable = async (path) => {
|
|
|
202
219
|
return false;
|
|
203
220
|
}
|
|
204
221
|
};
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
"import ctypes; ctypes.CDLL('libX11.so.6'); ctypes.CDLL('libXtst.so.6')",
|
|
213
|
-
]);
|
|
214
|
-
return true;
|
|
215
|
-
}
|
|
216
|
-
catch {
|
|
217
|
-
return false;
|
|
218
|
-
}
|
|
219
|
-
};
|
|
222
|
+
const uncomposedLinuxDemoRuntimeCheck = () => Promise.resolve({
|
|
223
|
+
name: "hopper-demo-runtime",
|
|
224
|
+
ok: false,
|
|
225
|
+
classification: "config_drift",
|
|
226
|
+
detail: "Linux Hopper private-display diagnostics were not composed",
|
|
227
|
+
remediation: "Run rea doctor through the production CLI adapter.",
|
|
228
|
+
});
|
|
220
229
|
const manualHopperPaths = async () => {
|
|
221
230
|
const paths = [];
|
|
222
231
|
for (const root of ["/Applications", join(homedir(), "Applications")]) {
|
|
@@ -134,10 +134,7 @@ const optionalHopperVersionCheck = async (host, hopperPath) => {
|
|
|
134
134
|
};
|
|
135
135
|
const optionalHopperDemoCheck = async (host, hopperPath) => host.platform !== "linux" || hopperPath === undefined
|
|
136
136
|
? undefined
|
|
137
|
-
:
|
|
138
|
-
remediation: "Rerun rea setup to install the Xvfb, xauth, Python, X11, and XTEST packages required for Linux demo sessions.",
|
|
139
|
-
classification: "missing_dependency",
|
|
140
|
-
});
|
|
137
|
+
: host.linuxDemoRuntimeCheck();
|
|
141
138
|
const optionalIlspyCheck = async (host) => {
|
|
142
139
|
if (host.configuredIlspyCmdPath === undefined)
|
|
143
140
|
return undefined;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Project doctor diagnostics for concise CLI output or explicit full detail. */
|
|
2
|
+
export const projectDoctorReport = (report, detail) => detail === "full" ? report : doctorSummary(report);
|
|
3
|
+
const doctorSummary = (report) => ({
|
|
4
|
+
healthy: report.healthy,
|
|
5
|
+
environment_healthy: report.environment_healthy,
|
|
6
|
+
scope: report.scope,
|
|
7
|
+
...(report.hopperPath === undefined
|
|
8
|
+
? {}
|
|
9
|
+
: { hopper_path: report.hopperPath }),
|
|
10
|
+
providers: (report.providerInspections ?? []).map((provider) => ({
|
|
11
|
+
id: provider.id,
|
|
12
|
+
configured: provider.configured,
|
|
13
|
+
available: provider.available,
|
|
14
|
+
provider_version: provider.providerVersion,
|
|
15
|
+
failed_checks: provider.checks.filter(({ ok }) => !ok).map(checkSummary),
|
|
16
|
+
})),
|
|
17
|
+
failed_scope_checks: report.scope_checks
|
|
18
|
+
.filter(({ ok }) => !ok)
|
|
19
|
+
.map(checkSummary),
|
|
20
|
+
informational_drift_count: report.informational_checks.filter(({ ok }) => !ok)
|
|
21
|
+
.length,
|
|
22
|
+
identity: report.identity === undefined
|
|
23
|
+
? null
|
|
24
|
+
: {
|
|
25
|
+
cli_package_version: report.identity.cli_package_version,
|
|
26
|
+
expected_skill_version: report.identity.expected_skill_version,
|
|
27
|
+
catalog: {
|
|
28
|
+
counts: report.identity.catalog.counts,
|
|
29
|
+
digests: report.identity.catalog.digests,
|
|
30
|
+
},
|
|
31
|
+
installations: report.identity.installations,
|
|
32
|
+
skill: report.identity.skill,
|
|
33
|
+
registrations: report.identity.registrations,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
const checkSummary = (check) => ({
|
|
37
|
+
name: check.name,
|
|
38
|
+
classification: check.classification,
|
|
39
|
+
...(check.detail === undefined ? {} : { detail: check.detail }),
|
|
40
|
+
...(check.remediation === undefined || check.remediation === null
|
|
41
|
+
? {}
|
|
42
|
+
: { remediation: check.remediation }),
|
|
43
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { doctorHealthy } from "./DoctorDiagnostics.js";
|
|
2
|
+
/** Normalize a caller-selected doctor readiness boundary. */
|
|
3
|
+
export const normalizeDoctorScope = (requested, target) => ({
|
|
4
|
+
mode: requested === undefined ? "audit-wide" : "explicit",
|
|
5
|
+
clients: uniqueSorted(requested?.clients ?? []),
|
|
6
|
+
providers: uniqueSorted(requested?.providers ?? []),
|
|
7
|
+
skill: requested?.skill === true,
|
|
8
|
+
target: target ?? null,
|
|
9
|
+
});
|
|
10
|
+
/** Partition diagnostics into required and informational scope checks. */
|
|
11
|
+
export const scopeDoctorChecks = (input) => {
|
|
12
|
+
const providerChecks = input.checks.filter((candidate) => isProviderCheck(candidate.name, input.providers.providerInspections));
|
|
13
|
+
const coreChecks = input.checks.filter(({ name }) => !isProviderCheck(name, input.providers.providerInspections) &&
|
|
14
|
+
name !== "skill:identity" &&
|
|
15
|
+
!name.startsWith("registration:"));
|
|
16
|
+
const clientChecks = input.scope.clients.map((client) => selectedRegistrationCheck(client, input.registrations.find((candidate) => candidate.client === client)));
|
|
17
|
+
const skillChecks = input.scope.skill
|
|
18
|
+
? [selectedSkillCheck(input.skillState, input.checks)]
|
|
19
|
+
: [];
|
|
20
|
+
const selectedProviderChecks = input.scope.providers.length === 0
|
|
21
|
+
? configuredProviderChecks(providerChecks, input.providers)
|
|
22
|
+
: input.scope.providers.flatMap((providerId) => selectedProviderChecksFor(providerId, providerChecks, input.providers));
|
|
23
|
+
const scopeChecks = [
|
|
24
|
+
...coreChecks,
|
|
25
|
+
...selectedProviderChecks,
|
|
26
|
+
...clientChecks,
|
|
27
|
+
...skillChecks,
|
|
28
|
+
];
|
|
29
|
+
const providerHealthy = input.scope.providers.length === 0
|
|
30
|
+
? doctorHealthy([...coreChecks, ...providerChecks, ...clientChecks, ...skillChecks], input.providers)
|
|
31
|
+
: selectedProviderChecks.every(({ ok }) => ok);
|
|
32
|
+
const selectedNames = new Set(scopeChecks.map(({ name }) => name));
|
|
33
|
+
return {
|
|
34
|
+
healthy: coreChecks.every(({ ok }) => ok) &&
|
|
35
|
+
clientChecks.every(({ ok }) => ok) &&
|
|
36
|
+
skillChecks.every(({ ok }) => ok) &&
|
|
37
|
+
providerHealthy,
|
|
38
|
+
scopeChecks,
|
|
39
|
+
informationalChecks: input.checks.filter(({ name }) => !selectedNames.has(name)),
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
const isProviderCheck = (name, inspections) => name.startsWith("hopper") ||
|
|
43
|
+
inspections?.some(({ id }) => doctorProviderCheckName(id, name)) === true;
|
|
44
|
+
const configuredProviderChecks = (checks, providers) => checks.filter(({ name }) => name.startsWith("hopper")
|
|
45
|
+
? providers.hopperConfigured
|
|
46
|
+
: providers.providerInspections?.some(({ id, configured }) => configured && doctorProviderCheckName(id, name)) === true);
|
|
47
|
+
const selectedProviderChecksFor = (providerId, checks, providers) => {
|
|
48
|
+
const selected = checks.filter(({ name }) => providerId === "hopper"
|
|
49
|
+
? name.startsWith("hopper")
|
|
50
|
+
: doctorProviderCheckName(providerId, name));
|
|
51
|
+
const available = providerId === "hopper"
|
|
52
|
+
? providers.hopperAvailable
|
|
53
|
+
: providers.providerInspections?.find(({ id }) => id === providerId)
|
|
54
|
+
?.available === true;
|
|
55
|
+
if (available && selected.every(({ ok }) => ok))
|
|
56
|
+
return selected;
|
|
57
|
+
if (selected.some(({ ok }) => !ok))
|
|
58
|
+
return selected;
|
|
59
|
+
return [
|
|
60
|
+
...selected,
|
|
61
|
+
{
|
|
62
|
+
name: `provider:${providerId}`,
|
|
63
|
+
ok: false,
|
|
64
|
+
classification: "missing_analysis_engine",
|
|
65
|
+
detail: `Requested provider ${providerId} is unavailable.`,
|
|
66
|
+
remediation: `Configure the ${providerId} provider, then rerun rea doctor.`,
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
};
|
|
70
|
+
const selectedRegistrationCheck = (client, status) => status === undefined
|
|
71
|
+
? {
|
|
72
|
+
name: `registration:${client}`,
|
|
73
|
+
ok: false,
|
|
74
|
+
classification: "config_drift",
|
|
75
|
+
detail: `Requested client ${client} was not detected.`,
|
|
76
|
+
remediation: `Install or select ${client}, then run rea setup --client ${client}.`,
|
|
77
|
+
}
|
|
78
|
+
: status.state === "aligned"
|
|
79
|
+
? {
|
|
80
|
+
name: `registration:${client}`,
|
|
81
|
+
ok: true,
|
|
82
|
+
classification: "healthy",
|
|
83
|
+
detail: status.config_path,
|
|
84
|
+
}
|
|
85
|
+
: registrationCheck(status);
|
|
86
|
+
const registrationCheck = (status) => ({
|
|
87
|
+
name: `registration:${status.client}`,
|
|
88
|
+
ok: false,
|
|
89
|
+
classification: "config_drift",
|
|
90
|
+
detail: status.config_path,
|
|
91
|
+
remediation: status.remediation ?? "Run rea setup, then restart the affected client.",
|
|
92
|
+
});
|
|
93
|
+
const selectedSkillCheck = (state, checks) => checks.find(({ name }) => name === "skill:identity") ?? {
|
|
94
|
+
name: "skill:identity",
|
|
95
|
+
ok: state === "aligned",
|
|
96
|
+
classification: state === "aligned" ? "healthy" : "config_drift",
|
|
97
|
+
...(state === "aligned"
|
|
98
|
+
? { detail: "Installed REA skill identity is aligned." }
|
|
99
|
+
: { remediation: "Run rea setup to update the installed REA skill." }),
|
|
100
|
+
};
|
|
101
|
+
const uniqueSorted = (values) => [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
102
|
+
const doctorProviderCheckName = (providerId, name) => name === providerId || name.startsWith(`${providerId}-`);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EvidenceReferenceError } from "../domain/errors.js";
|
|
2
|
+
import { err, ok } from "../domain/result.js";
|
|
3
|
+
/** Resolve IDs without accepting the digest-shaped identifier as proof itself. */
|
|
4
|
+
export const resolveEvidenceReferences = (lookup, evidenceIds, expected) => {
|
|
5
|
+
const records = [];
|
|
6
|
+
for (const evidenceId of evidenceIds) {
|
|
7
|
+
const record = lookup?.(evidenceId);
|
|
8
|
+
if (record === undefined)
|
|
9
|
+
return err(new EvidenceReferenceError(evidenceId, "missing", expectationDescription(expected), null));
|
|
10
|
+
if (expected !== undefined) {
|
|
11
|
+
const operations = expected.filter(({ operation }) => operation === record.operation);
|
|
12
|
+
if (operations.length === 0)
|
|
13
|
+
return err(new EvidenceReferenceError(evidenceId, "wrong_operation", unique(expected.map(({ operation }) => operation)).join(" | "), record.operation));
|
|
14
|
+
if (!operations.some(({ predicate }) => predicate === record.predicate_type))
|
|
15
|
+
return err(new EvidenceReferenceError(evidenceId, "wrong_predicate", unique(operations.map(({ predicate }) => predicate)).join(" | "), record.predicate_type));
|
|
16
|
+
}
|
|
17
|
+
records.push(record);
|
|
18
|
+
}
|
|
19
|
+
return ok(records);
|
|
20
|
+
};
|
|
21
|
+
const expectationDescription = (expected) => expected === undefined
|
|
22
|
+
? "Evidence in the current authority"
|
|
23
|
+
: expected
|
|
24
|
+
.map(({ operation, predicate }) => `${operation}:${predicate}`)
|
|
25
|
+
.join(" | ");
|
|
26
|
+
const unique = (values) => [...new Set(values)];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { AnalysisInputError, AnalysisProtocolError, } from "../domain/errors.js";
|
|
3
|
+
import { createEvidence, } from "../domain/evidence.js";
|
|
4
|
+
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
5
|
+
import { err, ok } from "../domain/result.js";
|
|
6
|
+
/** Parse one inventory projection and wrap its deterministic result in Evidence v2. */
|
|
7
|
+
export const projectInventoryEvidence = (options) => {
|
|
8
|
+
const parsed = options.schema.safeParse(options.rawInput);
|
|
9
|
+
if (!parsed.success)
|
|
10
|
+
return err(new AnalysisInputError(options.operation, { cause: parsed.error }));
|
|
11
|
+
try {
|
|
12
|
+
const result = options.project(parsed.data);
|
|
13
|
+
const first = parsed.data.inventory_evidence[0];
|
|
14
|
+
return ok(createEvidence(first?.subject === null || first?.subject === undefined
|
|
15
|
+
? undefined
|
|
16
|
+
: {
|
|
17
|
+
path: first.subject.local_path,
|
|
18
|
+
sha256: result.root_sha256,
|
|
19
|
+
format: options.subjectFormat(first),
|
|
20
|
+
}, options.provider, {
|
|
21
|
+
predicateType: options.predicateType,
|
|
22
|
+
operation: options.operation,
|
|
23
|
+
parameters: {
|
|
24
|
+
inventory_evidence_ids: [...result.source_evidence_ids],
|
|
25
|
+
limits: jsonValueSchema.parse(parsed.data.limits),
|
|
26
|
+
},
|
|
27
|
+
result: jsonValueSchema.parse(result),
|
|
28
|
+
rawResult: null,
|
|
29
|
+
confidence: "inferred",
|
|
30
|
+
authority: "analyst-inference",
|
|
31
|
+
environment: null,
|
|
32
|
+
limitations: result.limitations,
|
|
33
|
+
evidenceLinks: result.source_evidence_ids,
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
catch (cause) {
|
|
37
|
+
return err(cause instanceof TypeError || cause instanceof z.ZodError
|
|
38
|
+
? new AnalysisInputError(options.operation, { cause })
|
|
39
|
+
: new AnalysisProtocolError(options.protocolError, { cause }));
|
|
40
|
+
}
|
|
41
|
+
};
|
|
@@ -27,6 +27,18 @@ export const MANAGED_WORKFLOW_PROVIDER = {
|
|
|
27
27
|
name: "REA managed-code workflows",
|
|
28
28
|
version: "1",
|
|
29
29
|
};
|
|
30
|
+
/** Provider identity for deterministic Apple application projections. */
|
|
31
|
+
export const APPLE_APPLICATION_PROVIDER = {
|
|
32
|
+
id: "rea-apple-application",
|
|
33
|
+
name: "REA Apple application workflows",
|
|
34
|
+
version: "1",
|
|
35
|
+
};
|
|
36
|
+
/** Provider identity for deterministic Android application projections. */
|
|
37
|
+
export const ANDROID_APPLICATION_PROVIDER = {
|
|
38
|
+
id: "rea-android-application",
|
|
39
|
+
name: "REA Android application workflows",
|
|
40
|
+
version: "1",
|
|
41
|
+
};
|
|
30
42
|
/** Provider identity for deterministic static JavaScript application analysis. */
|
|
31
43
|
export const JAVASCRIPT_APPLICATION_PROVIDER = {
|
|
32
44
|
id: "rea-javascript-application",
|
|
@@ -7,7 +7,7 @@ export const createJavaScriptApplicationEvidence = (input, result) => createEvid
|
|
|
7
7
|
sha256: result.root_artifact_sha256,
|
|
8
8
|
format: result.format,
|
|
9
9
|
}, JAVASCRIPT_APPLICATION_PROVIDER, {
|
|
10
|
-
predicateType:
|
|
10
|
+
predicateType: `rea.javascript-application-analysis/v${String(result.schema_version)}`,
|
|
11
11
|
operation: "analyze_javascript_application",
|
|
12
12
|
parameters: parameters(input),
|
|
13
13
|
result: jsonValueSchema.parse(result),
|
|
@@ -7,7 +7,10 @@ import { managedApplicationGraphResultSchema } from "../domain/managedApplicatio
|
|
|
7
7
|
export const parseApplicationGraphEvidence = (input) => {
|
|
8
8
|
const evidence = parseEvidence(input);
|
|
9
9
|
if (evidence.operation === "analyze_javascript_application" &&
|
|
10
|
-
|
|
10
|
+
[
|
|
11
|
+
"rea.javascript-application-analysis/v1",
|
|
12
|
+
"rea.javascript-application-analysis/v2",
|
|
13
|
+
].includes(evidence.predicate_type) &&
|
|
11
14
|
providerMatches(evidence, JAVASCRIPT_APPLICATION_PROVIDER))
|
|
12
15
|
return staticApplicationSource(evidence);
|
|
13
16
|
if (evidence.operation === "reconcile_javascript_runtime" &&
|
|
@@ -25,6 +28,9 @@ const staticApplicationSource = (evidence) => {
|
|
|
25
28
|
evidence.confidence !== "derived")
|
|
26
29
|
throw new TypeError("JavaScript application Evidence authority or confidence is invalid");
|
|
27
30
|
const result = javascriptApplicationAnalysisResultSchema.parse(evidence.normalized_result);
|
|
31
|
+
if (evidence.predicate_type !==
|
|
32
|
+
`rea.javascript-application-analysis/v${String(result.schema_version)}`)
|
|
33
|
+
throw new TypeError("JavaScript application Evidence predicate does not match its result schema version");
|
|
28
34
|
analyzeJavaScriptApplicationInputSchema.parse({
|
|
29
35
|
input_path: result.input_path,
|
|
30
36
|
...evidence.parameters,
|
|
@@ -35,6 +41,7 @@ const staticApplicationSource = (evidence) => {
|
|
|
35
41
|
graph: result.graph,
|
|
36
42
|
kind: "static-application",
|
|
37
43
|
rootArtifactSha256: result.root_artifact_sha256,
|
|
44
|
+
semanticGraph: result.schema_version === 2 ? result.semantic_graph : null,
|
|
38
45
|
};
|
|
39
46
|
};
|
|
40
47
|
const staticRuntimeSource = (evidence) => {
|
|
@@ -52,6 +59,7 @@ const staticRuntimeSource = (evidence) => {
|
|
|
52
59
|
graph: result.graph,
|
|
53
60
|
kind: "static-runtime-reconciliation",
|
|
54
61
|
rootArtifactSha256: applicationLayer.root_artifact_sha256,
|
|
62
|
+
semanticGraph: null,
|
|
55
63
|
};
|
|
56
64
|
};
|
|
57
65
|
const managedApplicationSource = (evidence) => {
|
|
@@ -66,6 +74,7 @@ const managedApplicationSource = (evidence) => {
|
|
|
66
74
|
graph: result.graph,
|
|
67
75
|
kind: "managed-application",
|
|
68
76
|
rootArtifactSha256: result.root_artifact_sha256,
|
|
77
|
+
semanticGraph: null,
|
|
69
78
|
};
|
|
70
79
|
};
|
|
71
80
|
const assertApplicationSubject = (evidence, result) => {
|
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js";
|
|
3
3
|
import { analyzeJavaScriptApplicationInputSchema, javascriptApplicationAnalysisResultSchema, } from "../domain/javascriptApplicationAnalysis.js";
|
|
4
4
|
import { AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisProtocolError, ArtifactOperationError, PermissionRequiredError, } from "../domain/errors.js";
|
|
5
|
+
import { projectInputIssues } from "../domain/inputIssueProjection.js";
|
|
5
6
|
import { err, ok } from "../domain/result.js";
|
|
6
7
|
import { createJavaScriptApplicationEvidence } from "./JavaScriptApplicationEvidence.js";
|
|
7
8
|
import { reconstructJavaScriptArtifact } from "./JavaScriptArtifactReconstruction.js";
|
|
@@ -10,7 +11,7 @@ const OPERATION = "analyze_javascript_application";
|
|
|
10
11
|
export const analyzeJavaScriptApplication = async (authority, rawInput, options = {}) => {
|
|
11
12
|
const parsed = analyzeJavaScriptApplicationInputSchema.safeParse(rawInput);
|
|
12
13
|
if (!parsed.success)
|
|
13
|
-
return err(new AnalysisInputError(OPERATION));
|
|
14
|
+
return err(new AnalysisInputError(OPERATION, undefined, projectInputIssues(parsed.error.issues, rawInput)));
|
|
14
15
|
return analyzeJavaScriptApplicationValidated(authority, parsed.data, options);
|
|
15
16
|
};
|
|
16
17
|
/** Analyze input already parsed by a trusted adapter boundary. */
|
|
@@ -50,7 +51,7 @@ export const analyzeJavaScriptApplicationValidated = async (authority, input, op
|
|
|
50
51
|
}, options.signal);
|
|
51
52
|
const { electron_summary: summary, ...application } = reconstructed;
|
|
52
53
|
const result = javascriptApplicationAnalysisResultSchema.parse({
|
|
53
|
-
schema_version:
|
|
54
|
+
schema_version: 2,
|
|
54
55
|
...application,
|
|
55
56
|
summary,
|
|
56
57
|
limitations: reconstructed.graph.limitations,
|
|
@@ -14,6 +14,19 @@ export const createApplicationFeatureTraceEvidence = (parameters, result) => cre
|
|
|
14
14
|
limitations: result.limitations,
|
|
15
15
|
evidenceLinks: result.evidence_links,
|
|
16
16
|
});
|
|
17
|
+
/** Create derived Evidence for one bounded JavaScript semantic trace. */
|
|
18
|
+
export const createJavaScriptSemanticTraceEvidence = (parameters, result) => createEvidence(undefined, JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER, {
|
|
19
|
+
predicateType: "rea.javascript-semantic-trace/v1",
|
|
20
|
+
operation: "trace_javascript_semantics",
|
|
21
|
+
parameters,
|
|
22
|
+
result: jsonValueSchema.parse(result),
|
|
23
|
+
rawResult: null,
|
|
24
|
+
confidence: "inferred",
|
|
25
|
+
authority: "analyst-inference",
|
|
26
|
+
environment: null,
|
|
27
|
+
limitations: result.limitations,
|
|
28
|
+
evidenceLinks: result.evidence_links,
|
|
29
|
+
});
|
|
17
30
|
/** Create derived Evidence for one tiered application version comparison. */
|
|
18
31
|
export const createApplicationVersionComparisonEvidence = (parameters, result) => createEvidence(undefined, JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER, {
|
|
19
32
|
predicateType: "rea.application-version-comparison/v1",
|
|
@@ -27,3 +40,16 @@ export const createApplicationVersionComparisonEvidence = (parameters, result) =
|
|
|
27
40
|
limitations: result.limitations,
|
|
28
41
|
evidenceLinks: result.evidence_links,
|
|
29
42
|
});
|
|
43
|
+
/** Create derived Evidence for one bounded static export-shape comparison. */
|
|
44
|
+
export const createJavaScriptExportShapeComparisonEvidence = (parameters, result) => createEvidence(undefined, JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER, {
|
|
45
|
+
predicateType: "rea.javascript-export-shape-comparison/v1",
|
|
46
|
+
operation: "compare_javascript_export_shapes",
|
|
47
|
+
parameters,
|
|
48
|
+
result: jsonValueSchema.parse(result),
|
|
49
|
+
rawResult: null,
|
|
50
|
+
confidence: "inferred",
|
|
51
|
+
authority: "analyst-inference",
|
|
52
|
+
environment: null,
|
|
53
|
+
limitations: result.limitations,
|
|
54
|
+
evidenceLinks: result.evidence_links,
|
|
55
|
+
});
|
|
@@ -3,11 +3,13 @@ import { AnalysisInputError, AnalysisProtocolError, } from "../domain/errors.js"
|
|
|
3
3
|
import { projectInputIssues } from "../domain/inputIssueProjection.js";
|
|
4
4
|
import { compareJavaScriptApplicationVersions } from "../domain/javascriptApplicationVersionComparison.js";
|
|
5
5
|
import { compareApplicationVersionsInputSchema } from "../domain/javascriptApplicationVersionComparisonSchemas.js";
|
|
6
|
+
import { compareJavaScriptExportShapes } from "../domain/javascriptExportShapeComparison.js";
|
|
7
|
+
import { compareJavaScriptExportShapesInputSchema } from "../domain/javascriptExportShapeComparisonSchemas.js";
|
|
6
8
|
import { traceApplicationFeature } from "../domain/javascriptFeatureTrace.js";
|
|
7
9
|
import { traceApplicationFeatureInputSchema } from "../domain/javascriptFeatureTraceSchemas.js";
|
|
8
10
|
import { err, ok } from "../domain/result.js";
|
|
9
11
|
import { parseApplicationGraphEvidence, parseNativeApplicationEvidence, } from "./JavaScriptApplicationEvidenceGraph.js";
|
|
10
|
-
import { createApplicationFeatureTraceEvidence, createApplicationVersionComparisonEvidence, } from "./JavaScriptApplicationWorkflowEvidence.js";
|
|
12
|
+
import { createApplicationFeatureTraceEvidence, createApplicationVersionComparisonEvidence, createJavaScriptExportShapeComparisonEvidence, } from "./JavaScriptApplicationWorkflowEvidence.js";
|
|
11
13
|
/** Authenticate Evidence and derive one bounded cross-layer feature trace. */
|
|
12
14
|
export const traceApplicationFeatureEvidence = (rawInput) => {
|
|
13
15
|
const operation = "trace_application_feature";
|
|
@@ -85,6 +87,52 @@ export const compareApplicationVersionsEvidenceValidated = (input) => {
|
|
|
85
87
|
return workflowFailure(operation, cause);
|
|
86
88
|
}
|
|
87
89
|
};
|
|
90
|
+
/**
|
|
91
|
+
* Authenticate both graphs and compare one exact export return shape.
|
|
92
|
+
* @public
|
|
93
|
+
*/
|
|
94
|
+
export const compareJavaScriptExportShapesEvidence = (rawInput) => {
|
|
95
|
+
const operation = "compare_javascript_export_shapes";
|
|
96
|
+
const parsed = compareJavaScriptExportShapesInputSchema.safeParse(rawInput);
|
|
97
|
+
if (!parsed.success)
|
|
98
|
+
return err(new AnalysisInputError(operation, undefined, projectInputIssues(parsed.error.issues, rawInput)));
|
|
99
|
+
return compareJavaScriptExportShapesEvidenceValidated(parsed.data);
|
|
100
|
+
};
|
|
101
|
+
/** Compare exact export shapes from input parsed by a trusted adapter. */
|
|
102
|
+
export const compareJavaScriptExportShapesEvidenceValidated = (input) => {
|
|
103
|
+
const operation = "compare_javascript_export_shapes";
|
|
104
|
+
try {
|
|
105
|
+
const left = parseApplicationGraphEvidence(input.left);
|
|
106
|
+
const right = parseApplicationGraphEvidence(input.right);
|
|
107
|
+
const result = compareJavaScriptExportShapes({
|
|
108
|
+
left: {
|
|
109
|
+
evidenceId: left.evidence.evidence_id,
|
|
110
|
+
graph: left.graph,
|
|
111
|
+
modulePath: input.left_module_path,
|
|
112
|
+
exportName: input.left_export_name,
|
|
113
|
+
},
|
|
114
|
+
right: {
|
|
115
|
+
evidenceId: right.evidence.evidence_id,
|
|
116
|
+
graph: right.graph,
|
|
117
|
+
modulePath: input.right_module_path,
|
|
118
|
+
exportName: input.right_export_name,
|
|
119
|
+
},
|
|
120
|
+
limits: input.limits,
|
|
121
|
+
});
|
|
122
|
+
return ok(createJavaScriptExportShapeComparisonEvidence({
|
|
123
|
+
left_evidence_id: left.evidence.evidence_id,
|
|
124
|
+
right_evidence_id: right.evidence.evidence_id,
|
|
125
|
+
left_module_path: input.left_module_path,
|
|
126
|
+
left_export_name: input.left_export_name,
|
|
127
|
+
right_module_path: input.right_module_path,
|
|
128
|
+
right_export_name: input.right_export_name,
|
|
129
|
+
limits: input.limits,
|
|
130
|
+
}, result));
|
|
131
|
+
}
|
|
132
|
+
catch (cause) {
|
|
133
|
+
return workflowFailure(operation, cause);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
88
136
|
const workflowFailure = (operation, cause) => err(cause instanceof z.ZodError || cause instanceof TypeError
|
|
89
137
|
? new AnalysisInputError(operation)
|
|
90
138
|
: new AnalysisProtocolError("JavaScript application workflow produced an invalid result", { cause }));
|