rea-agents 1.1.0 → 1.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 +94 -28
- package/bridge/hopper_bridge.py +161 -12
- package/dist/application/AnalysisSnapshotCache.js +131 -0
- package/dist/application/AnalysisSnapshotFiles.js +31 -0
- package/dist/application/ArtifactInventory.js +84 -44
- package/dist/application/AuthorizedArtifactInventory.js +16 -0
- package/dist/application/BinarySession.js +66 -36
- package/dist/application/BinarySessionPort.js +1 -0
- package/dist/application/BoundedJsonFiles.js +109 -0
- package/dist/application/CommandShimReplay.js +136 -0
- package/dist/application/CrossVersionInventory.js +98 -0
- package/dist/application/CrossVersionInvestigation.js +295 -0
- package/dist/application/DirectAnalysis.js +115 -22
- package/dist/application/Doctor.js +30 -1
- package/dist/application/EvidenceBundleFiles.js +16 -101
- package/dist/application/EvidenceLedger.js +3 -2
- package/dist/application/InvestigationProviders.js +48 -0
- package/dist/application/InvestigationWorkspaceStore.js +214 -0
- package/dist/application/LinuxHopper.js +72 -48
- package/dist/application/ProcessCaptureAuthority.js +25 -0
- package/dist/application/ProcessCaptureCapability.js +23 -0
- package/dist/application/ProcessCaptureError.js +17 -0
- package/dist/application/ProcessCaptureLifecycle.js +287 -0
- package/dist/application/ProcessCheckpoints.js +129 -0
- package/dist/application/ProcessCli.js +128 -0
- package/dist/application/ProcessEvidence.js +38 -0
- package/dist/application/ProcessHarness.js +252 -272
- package/dist/application/ProcessNormalization.js +10 -1
- package/dist/application/ProcessOwnership.js +39 -1
- package/dist/application/ProcessSampling.js +39 -23
- package/dist/application/ReferenceSourceImportEntries.js +18 -3
- package/dist/application/ReferenceSourceImportTypes.js +32 -0
- package/dist/application/Setup.js +44 -96
- package/dist/application/SetupClients.js +19 -0
- package/dist/application/SetupInstallFailure.js +53 -0
- package/dist/application/SetupPlan.js +31 -0
- package/dist/application/SetupSkill.js +44 -0
- package/dist/application/TerminalRenderer.js +92 -0
- package/dist/application/Uninstall.js +33 -23
- package/dist/application/UnknownEvidence.js +33 -0
- package/dist/application/Upgrade.js +1 -1
- package/dist/application/runtime.js +2 -2
- package/dist/artifacts/ArtifactProvider.js +20 -11
- package/dist/artifacts/ArtifactReader.js +3 -1
- package/dist/artifacts/AsarArtifactReader.js +8 -1
- package/dist/artifacts/DirectoryArtifactReader.js +1 -0
- package/dist/artifacts/MachOSliceArtifactReader.js +1 -0
- package/dist/artifacts/NativeDmgArtifactReader.js +151 -0
- package/dist/artifacts/ZipArtifactReader.js +1 -0
- package/dist/cli.js +57 -32
- package/dist/cliEvidenceCommands.js +11 -12
- package/dist/cliInvestigationCommands.js +86 -0
- package/dist/cliOutput.js +41 -0
- package/dist/cliProcessCommands.js +29 -0
- package/dist/config.js +41 -24
- package/dist/contracts/artifactToolContracts.js +1 -0
- package/dist/contracts/investigationExamples.js +3 -3
- package/dist/contracts/processCaptureExample.js +50 -7
- package/dist/contracts/promptContracts.js +256 -0
- package/dist/contracts/sessionLifecycleInputs.js +11 -0
- package/dist/contracts/toolContractTypes.js +1 -0
- package/dist/contracts/toolContracts.js +13 -8
- package/dist/contracts/toolOutputSchemas.js +33 -4
- package/dist/domain/analysisSnapshot.js +149 -0
- package/dist/domain/changedBehavior.js +32 -9
- package/dist/domain/errors.js +186 -39
- package/dist/domain/evidence.js +4 -2
- package/dist/domain/evidenceBundle.js +28 -0
- package/dist/domain/hopperStartupFailure.js +55 -0
- package/dist/domain/investigationWorkspace.js +214 -0
- package/dist/domain/jsonValue.js +2 -0
- package/dist/domain/nativeInspection.js +3 -2
- package/dist/domain/processCapture.js +100 -293
- package/dist/domain/processCaptureValidation.js +124 -0
- package/dist/domain/processComparison.js +177 -32
- package/dist/domain/processScenario.js +370 -0
- package/dist/domain/reconstructionVerification.js +3 -3
- package/dist/domain/staticRuntimeCorrelation.js +3 -2
- package/dist/hopper/BridgeLauncher.js +47 -20
- package/dist/hopper/HopperClient.js +17 -2
- package/dist/hopper/HopperProvider.js +1 -0
- package/dist/identity.js +1 -0
- package/dist/main.js +47 -24
- package/dist/server/createServer.js +2 -0
- package/dist/server/promptCompletion.js +144 -0
- package/dist/server/registerEnhancedTools.js +2 -6
- package/dist/server/registerEvidenceTools.js +2 -8
- package/dist/server/registerFunctionComparisonTool.js +1 -1
- package/dist/server/registerInvestigationTools.js +31 -11
- package/dist/server/registerOfficialTools.js +6 -13
- package/dist/server/registerProcessComparisonTool.js +28 -14
- package/dist/server/registerPrompts.js +67 -0
- package/dist/server/registerSessionStatusTool.js +11 -0
- package/dist/server/registerSessionTools.js +55 -43
- package/dist/server/sessionEvidence.js +2 -8
- package/dist/server/sessionToolPolicies.js +2 -48
- package/dist/server/toolResult.js +7 -3
- package/install.sh +11 -11
- package/package.json +9 -3
- package/scripts/hopper-demo-x11.py +349 -0
- package/scripts/prepare-node-pty.mjs +35 -0
- package/scripts/rea.mjs +6 -3
- package/skills/rea-analysis/SKILL.md +27 -5
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { parseConfig } from "../config.js";
|
|
3
|
+
import { AnalysisError, projectAnalysisError } from "../domain/errors.js";
|
|
4
|
+
import { createEvidence, parseEvidence } from "../domain/evidence.js";
|
|
5
|
+
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
6
|
+
import { compareProcessCaptures, LEGACY_PROCESS_CAPTURE_MESSAGE, parseProcessScenario, parseProcessCapture, } from "../domain/processCapture.js";
|
|
7
|
+
import { captureProcessScenario } from "./ProcessHarness.js";
|
|
8
|
+
import { PROCESS_PROVIDER, createProcessCaptureEvidence, } from "./ProcessEvidence.js";
|
|
9
|
+
const MAX_INPUT_BYTES = 64 * 1024 * 1024;
|
|
10
|
+
/** Distinguish a safe process-command failure from successful Evidence. */
|
|
11
|
+
export const isProcessCliErrorOutput = (value) => typeof value === "object" &&
|
|
12
|
+
value !== null &&
|
|
13
|
+
"error" in value &&
|
|
14
|
+
value.error === "Process command failed" &&
|
|
15
|
+
"category" in value &&
|
|
16
|
+
typeof value.category === "string" &&
|
|
17
|
+
"message" in value &&
|
|
18
|
+
typeof value.message === "string";
|
|
19
|
+
/** Capture one JSON scenario through the same policy and evidence contract as MCP. */
|
|
20
|
+
export const captureProcessScenarioFile = async (path) => {
|
|
21
|
+
try {
|
|
22
|
+
const input = await readJson(path);
|
|
23
|
+
let scenario;
|
|
24
|
+
try {
|
|
25
|
+
scenario = parseProcessScenario(input);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new ProcessCliFailure("invalid_input", "Process scenario is invalid. Check its required fields and limits, then try again.");
|
|
29
|
+
}
|
|
30
|
+
const config = parseConfig(process.env);
|
|
31
|
+
if (!config.ok)
|
|
32
|
+
return cliAnalysisError(config.error);
|
|
33
|
+
const captured = await captureProcessScenario(scenario, config.value.processExecutionPolicy);
|
|
34
|
+
if (!captured.ok)
|
|
35
|
+
return cliAnalysisError(captured.error);
|
|
36
|
+
return createProcessCaptureEvidence(scenario, captured.value);
|
|
37
|
+
}
|
|
38
|
+
catch (cause) {
|
|
39
|
+
return projectProcessCliError(cause);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
/** Compare two capture Evidence files and emit derived comparison Evidence. */
|
|
43
|
+
export const compareProcessEvidenceFiles = async (leftPath, rightPath) => {
|
|
44
|
+
try {
|
|
45
|
+
const left = parseCaptureEvidence(await readJson(leftPath));
|
|
46
|
+
const right = parseCaptureEvidence(await readJson(rightPath));
|
|
47
|
+
const comparison = compareProcessCaptures(left.capture, right.capture);
|
|
48
|
+
return createEvidence(undefined, PROCESS_PROVIDER, {
|
|
49
|
+
predicateType: "rea.process-comparison/v3",
|
|
50
|
+
operation: "compare_process_captures",
|
|
51
|
+
parameters: {
|
|
52
|
+
left_evidence_id: left.id,
|
|
53
|
+
right_evidence_id: right.id,
|
|
54
|
+
left_normalization: left.capture.normalization,
|
|
55
|
+
right_normalization: right.capture.normalization,
|
|
56
|
+
},
|
|
57
|
+
result: jsonValueSchema.parse(comparison),
|
|
58
|
+
confidence: "derived",
|
|
59
|
+
authority: "analyst-inference",
|
|
60
|
+
limitations: comparison.limitations,
|
|
61
|
+
evidenceLinks: [left.id, right.id],
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (cause) {
|
|
65
|
+
return projectProcessCliError(cause);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const parseCaptureEvidence = (input) => {
|
|
69
|
+
const evidence = parseEvidence(input);
|
|
70
|
+
if (evidence.operation !== "capture_process_scenario" ||
|
|
71
|
+
evidence.predicate_type !== "rea.process-capture/v4" ||
|
|
72
|
+
evidence.provider.id !== PROCESS_PROVIDER.id ||
|
|
73
|
+
evidence.provider.version !== PROCESS_PROVIDER.version) {
|
|
74
|
+
if (evidence.predicate_type === "rea.process-capture/v3")
|
|
75
|
+
throw new ProcessCliFailure("invalid_input", LEGACY_PROCESS_CAPTURE_MESSAGE);
|
|
76
|
+
throw new ProcessCliFailure("invalid_input", "Capture evidence is not from the current process-capture workflow. Create new capture evidence, then try again.");
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
id: evidence.evidence_id,
|
|
80
|
+
capture: parseProcessCapture(evidence.normalized_result),
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
const readJson = async (path) => {
|
|
84
|
+
let bytes;
|
|
85
|
+
try {
|
|
86
|
+
bytes = await readFile(path);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
throw new ProcessCliFailure("invalid_input", "Process input file could not be read. Check that the path exists and is readable.");
|
|
90
|
+
}
|
|
91
|
+
if (bytes.length > MAX_INPUT_BYTES)
|
|
92
|
+
throw new ProcessCliFailure("truncated", "Process input file is too large. Reduce it below 64 MiB, then try again.");
|
|
93
|
+
try {
|
|
94
|
+
return JSON.parse(bytes.toString("utf8"));
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
throw new ProcessCliFailure("invalid_input", "Process input file is not valid JSON. Repair the file, then try again.");
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
class ProcessCliFailure extends Error {
|
|
101
|
+
category;
|
|
102
|
+
userMessage;
|
|
103
|
+
constructor(category, userMessage) {
|
|
104
|
+
super(userMessage);
|
|
105
|
+
this.category = category;
|
|
106
|
+
this.userMessage = userMessage;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const cliAnalysisError = (error) => ({
|
|
110
|
+
error: "Process command failed",
|
|
111
|
+
...projectAnalysisError(error),
|
|
112
|
+
});
|
|
113
|
+
/** Project any process CLI failure without exposing its cause. */
|
|
114
|
+
export const projectProcessCliError = (cause) => {
|
|
115
|
+
if (cause instanceof ProcessCliFailure)
|
|
116
|
+
return {
|
|
117
|
+
error: "Process command failed",
|
|
118
|
+
category: cause.category,
|
|
119
|
+
message: cause.userMessage,
|
|
120
|
+
};
|
|
121
|
+
if (cause instanceof AnalysisError)
|
|
122
|
+
return cliAnalysisError(cause);
|
|
123
|
+
return {
|
|
124
|
+
error: "Process command failed",
|
|
125
|
+
category: "execution_failure",
|
|
126
|
+
message: "Process command could not complete. Check the input files and run `rea doctor`, then try again.",
|
|
127
|
+
};
|
|
128
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { createEvidence } from "../domain/evidence.js";
|
|
2
|
+
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
3
|
+
import { parseProcessCapture } from "../domain/processCapture.js";
|
|
4
|
+
/** Provider identity for controlled Process Capture v4 evidence. */
|
|
5
|
+
export const PROCESS_PROVIDER = {
|
|
6
|
+
id: "rea-process",
|
|
7
|
+
name: "REA deterministic process harness",
|
|
8
|
+
version: "3",
|
|
9
|
+
};
|
|
10
|
+
/** Project one process scenario into secret-free Evidence parameters. */
|
|
11
|
+
const processEvidenceParameters = (scenario) => ({
|
|
12
|
+
executable_name: scenario.executable.split("/").at(-1) ?? scenario.executable,
|
|
13
|
+
argument_count: scenario.arguments.length,
|
|
14
|
+
event_count: scenario.events.length,
|
|
15
|
+
filesystem_root_count: scenario.filesystem_roots.length,
|
|
16
|
+
checkpoint_count: scenario.checkpoints.length,
|
|
17
|
+
command_shim_count: scenario.command_shims.length,
|
|
18
|
+
normalization: scenario.normalization,
|
|
19
|
+
});
|
|
20
|
+
/** Create one canonical observed Process Capture v4 Evidence record. */
|
|
21
|
+
export const createProcessCaptureEvidence = (scenario, capture) => {
|
|
22
|
+
const validatedCapture = parseProcessCapture(capture);
|
|
23
|
+
return createEvidence(undefined, PROCESS_PROVIDER, {
|
|
24
|
+
predicateType: "rea.process-capture/v4",
|
|
25
|
+
operation: "capture_process_scenario",
|
|
26
|
+
parameters: processEvidenceParameters(scenario),
|
|
27
|
+
result: jsonValueSchema.parse(validatedCapture),
|
|
28
|
+
confidence: "observed",
|
|
29
|
+
authority: "controlled-replay",
|
|
30
|
+
environment: {
|
|
31
|
+
id: `${process.platform}-${process.arch}`,
|
|
32
|
+
platform: process.platform,
|
|
33
|
+
architecture: process.arch,
|
|
34
|
+
isolation: "process",
|
|
35
|
+
},
|
|
36
|
+
limitations: validatedCapture.limitations,
|
|
37
|
+
});
|
|
38
|
+
};
|