* feat(jeb): add JEB engine provider over its MCP interface
Add a bring-your-own JEB provider that serves project, unit, and
decompilation inspection from a caller-started JEB client speaking MCP
(streamable HTTP, selected with REA_JEB_MCP_URL). Expose four provider-neutral
operations through shared CLI/MCP workflows: inspect_jeb_client,
open_jeb_project, list_jeb_units, and decompile_jeb_item, each returning
Evidence with engine identity, endpoint, and preserved refusal reasons.
The adapter keeps JEB's envelope semantics: success fields are parsed
format-aware at the boundary, message-only refusals become unsupported-target
errors with the engine's own reason, transport failures become availability
failures with recovery guidance, and unit pagination derives coverage from the
engine's 100-item page cap. Explicit unknowns (implicitly selected unit,
omitted filters) are reported instead of guessed.
Verified against a real JEB 5.48.0 licensed build serving jeb-mcp-server 1.3.0
headless: client inspection, unit listing, and method decompilation were
exercised through the CLI, MCP boundary, and scripts/verify-jeb.mjs.
JEB 5.48.0 headless instances do not advertise open_project; the refusal is
preserved and documented.
* fix(jeb): verify against a real signed APK and fix CLI option surface
Verify the provider against a locally built, v1/v2/v3-signed probe APK
(binary manifest, classes.dex with a launcher activity) on JEB 5.48.0: the
full unit tree (apk, manifest, three certificate units, dex bytecode,
decompiler), wildcard-filtered and paginated unit listing with derived
coverage, parent-restricted listing, and launcher-activity method
decompilation through both CLI and MCP, including dexdec's inline
constant folding of the probe's obfuscated tag.
Move list-jeb-units filter/pagination and decompile-jeb-item unit selection
from positional arguments to options; the MCP schemas are unchanged.
* fix(jeb): preserve engine refusals through the real MCP boundary
Testing against the published Signal 8.30.3 universal APK exposed a boundary
bug the scripted provider tests missed: decodeJebToolResult raised a protocol
error for isError results before the provider could map JEB's
{success:false, message} envelope, so real engine refusals surfaced as
unreadable output instead of the engine's own reason. Decode refusal
envelopes like any structured result and let the provider preserve the
reason; cover the decoder directly, including contentless and unparseable
results.
Signal verification: full 109 MB R8/Kotlin/Compose APK with four signature
schemes and native arm64 ELF units parsed; MainActivity.onCreate and R8
synthetic lambdas decompiled through CLI and MCP; paginated, filtered, and
parent-restricted unit listing; refusal path confirmed on the live engine.
* docs(jeb): record Flutter Gallery verification on the real-engine lane
Verify the provider against the official Flutter Gallery 2.9.2 release APK
(112 MB): per-ABI libapp.so Dart AOT snapshot images analyzed as native code
with 75k methods on arm64, snapshot internals and wrapper methods decompiled
through both CLI and MCP with explicit unit selection, decoded manifest, and
filtered native-library unit discovery. Note that JEB 5.48.0 headless does
not expose the dedicated Dart snapshot processor or run_script; both remain
GUI-only engine surfaces.
* docs(jeb): translate the README JEB row for every supported language
The JEB row was inserted in English across all translated READMEs; each now
carries its own label, capability summary, requirements, and guide link
following that language's Android-row conventions.
* fix(jeb): enforce local endpoints and preserve cancellation
* fix(jeb): refuse redirects across the local MCP boundary
---------
Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
* fix(javascript): accept the Wakaru 1.x release line and verify 1.14.0
Exact --version equality rejected every Wakaru build except 1.13.0, and
strict report schemas rejected any added field, so each upstream release
broke recovery until REA re-pinned. Wakaru now documents that --version,
--json and provenance.json change only by addition within a major version.
Admit ^1.13.0 with the verified/compatible split used for Binwalk and
Unblob, report the observed version instead of the pinned constant, and
add a limitation for unverified releases. Parse reports with loose
objects and keep the reported module status as a string; path, identity,
range and file-set checks stay exact.
Move the audited pin, submodule, CI binary and verifier to 1.14.0, and
document where to get the binary from the refusal message.
* fix(javascript): project known Wakaru warning fields
---------
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
* fix(ghidra): clear wrong no-return flags before serving a session
Auto-analysis can flag ordinary functions as no-return (stream readers,
__cxa_guard_acquire, ...). Their callers then end at the call and the
decompiler truncates them. Run a postScript before the bridge that clears the
flag on functions containing a real RET and re-disassembles the call sites that
were terminators.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* fix(ghidra): refit in place and scope no-return call-site repair
Keep function types by refitting the owning functions with fixupFunctionBody
instead of removing and recreating them. Only redo call sites whose callee was
actually cleared (including thunks to it), skip sites followed by a function
start or x86 padding so real end calls do not run on, and always log the result.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* fix(ghidra): constrain no-return repair to admitted return evidence
---------
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
* feat(adb): acquire installed APK sets from connected Android devices
Add a read-only ADB device-acquisition family over the caller's adb binary:
inspect_adb_client, list_adb_devices, inspect_adb_device, list_adb_packages,
and pull_adb_package, exposed through the CLI and MCP with shared admission,
Evidence provenance (binary, version, serial, transport), and fixed argv
vectors that never reach a shell.
pull_adb_package acquires the complete split set reported by pm path into a
package-named directory that must not exist, digesting every file with
SHA-256 and keeping per-file failure reasons and partial coverage. Device
kind is reported as an inference with its basis; getprop whitelisting keeps
build identity bounded. REA installs nothing and never manages devices or
emulators; the first device query may start the caller's local adb server,
recorded when observed.
Verified against adb 34.0.5 on Linux with an Android 14 (API 34) x86_64
emulator: full 224-package inventory, a real two-APK split set pulled with
byte-exact digests, and a 73.9 MB system-package pull. npm run verify:adb
records the lane; parser goldens come from the same device. READMEs carry
the new row in every supported language.
* feat(adb): complete the adb surface with observation, transfer, and lifecycle tools
Extend the ADB family from five to twenty-four operations, all through
fixed adb argument vectors with no shell exposure:
Observation: read_adb_logcat (bounded dump, count/buffer/pid), inspect_adb_package
(dumpsys package projection), list_adb_processes (ps -A), list_adb_directory
(ls -la with kinds and symlink targets), list_adb_features (hex GL versions),
list_adb_services (AIDL slash-suffixed names), inspect_adb_display (wm size and
density), inspect_adb_window (focus declarations), read_adb_setting (device-side
nulls reported as such), capture_adb_screen (exec-out screencap with PNG
dimensions), collect_adb_bugreport (digested device archive).
Transfer and search: pull_adb_file and push_adb_file (device-side sha256sum
verification, explicit overwrite authority), resolve_adb_packages (substring
package search with exact-match flag — the find step of an easy get).
Lifecycle for dynamic analysis, each declaring mutatesTarget:
install_adb_package and uninstall_adb_package preserving the device's
Success/Failure verdict, start_adb_app (resolve-activity then am start -W),
start_adb_activity (typed extras as --es/--ez/--ei/--el/--ef), and stop_adb_app
(am force-stop).
Verified end-to-end against adb 34.0.5 on Linux with an Android 14 (API 34)
x86_64 emulator: 287 services, 92 features, split-set pulls with byte-exact
digests, verified push/pull roundtrip, sized screen capture, and the full
install → resolve → start → observe-in-ps → force-stop → uninstall lifecycle.
Fixed a v-mode regex incompatibility in the settings key pattern and added
argument descriptions required by the CLI catalog audit.
* fix(adb): quote remote shell operands and protect captured output
* test(adb): cover bugreport destinations containing spaces
---------
Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
* fix: bind identity and coverage to the producing rule
Logical paths, container families, examined bytes, path-segment conventions, destination collisions, file-id leases, Mach-O CPU selection, and firmware cleanup now follow the observation that owns each rule.
* fix: fail unmatched Mach-O slices and keep firmware roots independent
A fat target whose architecture lipo did not list now stops before slice tools run. Chained fixups still count unread LC_DYLD_INFO rebase bytes, and a firmware cleanup failure no longer blocks the next workspace.
* test: cover path identity and runtime families at the projection boundary
NFC joins and segment conventions are now asserted by the path resolver, the Apple projection, and a real APK inventory instead of helper unit tests.
* test: expect unread dyld rebase bytes in the Apple dispatch fixture
The legacy LC_DYLD_INFO fixture keeps a rebase range this reader does not decode, so the public CLI and MCP check now requires that partial coverage beside the bind opcodes.
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* refactor(setup): resolve skill destinations per client
* fix(setup): honor active client configuration and skill roots
* fix(setup): validate effective client scopes and Gemini trust
* fix(setup): treat empty OpenCode overrides as unset
An empty OPENCODE_CONFIG_DIR now stays on the XDG directory, and doctor
and setup inspect global OpenCode files when a custom directory is absent.
Uninstall reports one status per client so a missing earlier layer does
not hide a removed registration.
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* feat: add Hermes as a supported MCP client
Hermes Agent reads stdio MCP servers from `mcp_servers.<name>` in
`config.yaml`. REA had no Hermes client, so setup could not register it and
Hermes users had to wire the server up by hand.
- SupportedClients: add the `hermes` format and client definition, resolving
the config path from HERMES_HOME, else the platform default that Hermes's own
resolver uses (LOCALAPPDATA/hermes on Windows, ~/.hermes elsewhere), including
HERMES_DATA_DIR_SUFFIX.
- ClientConfigurationDocument: parse and serialize Hermes YAML, upserting the
rea entry into the parsed document so user comments and unrelated settings are
preserved; emit `enabled: true` since Hermes connects entries unless disabled.
- ClientRegistrationStatus: forward the Hermes location variables so status
checks resolve the same path as setup.
- Tests: cover path resolution on both platforms and the register/read/uninstall
round trip, and clear the Hermes location variables between tests.
- delilah 🌸
* docs: document the Hermes client and its config path
- delilah 🌸
* refactor(setup): resolve skill destinations per client
* fix(setup): install Hermes skills in the active profile
* fix(setup): identify each client skill action uniquely
---------
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Verify five native operations through the public CLI and real SDK stdio MCP using a source-built macOS fixture. Retain normalized provenance, response parity and unchanged input bytes.
Refs #1430, #1065, #723.
`--json` / `--format json` always indented its streamed result. Agents and
scripts read REA through pipes and redirects, where indentation carries no
information: on real application results it added 16-45% model tokens
(o200k proxy) and 25-73% bytes. The skill's CLI fallback uses `--json`.
Indent only when stdout is a TTY, as `gh --json` does; piped or redirected
JSON is compact. The JSON value, `jsonl`, `--filter-output`,
`--full-output` and the token-window paths are unchanged. `jq .` restores
indentation for files.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
inspect_binary_layout and inspect_recorded_crash passed the decoded report
as both result and rawResult, so every Evidence record carried the whole
report twice (and an MCP response four times, counting its text copy).
The decoded report is the only representation, so raw_result is now null,
as for other single-representation operations.
The real pwntools verifiers asserted the duplicate; they now assert null.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The dense jump-table oracles (inspect-native-api CLI and the
analyze_function dossier) ran against the -O0 debug fixture, which
assumes the host compiler lowers dense switches to tables at -O0. GCC 16
and later expand them as compare chains instead, so on those hosts the
lane rejected a correct provider and Ghidra build with empty
jump_tables.
Build the same inventory source once more at -O2 as a dedicated
jump-table variant, run both strict dense oracles there, and keep the
debug dossier at its complete generic shape. The dedicated switch lane
already compiles at -O2 for the same reason.
Retain primitive and nested array types with typed paths, and compare only mutually observed body shapes while preserving selected coverage uncertainty. Return full untrusted WebMCP input declarations with canonical digests, without resolving references or invoking tools.
BREAKING CHANGE: JSON shape paths now contain typed property and array-element segments. WebMCP input_schema_shape is replaced by input_schema and input_schema_sha256, retaining declared examples and defaults.
The real-Hopper navigation probe derived its interior coordinate as
anchor + 1, which assumes the fixture procedure's first instruction is
longer than one byte. Host toolchains without endbr64-style prologue
padding (Kali gcc 16, or any build with -fcf-protection=none) compile
rea_entry to start with the one-byte push rbp, so anchor + 1 is itself
an instruction boundary: goto_address correctly observes that boundary
and the boundary-contract run rejects a correct bridge.
Advance the probe to the first instruction followed by a coordinate gap
larger than one byte and derive the interior-coordinate assertions from
that instruction, so the probed coordinate is never an analyzed-object
boundary on either prologue encoding.
Share parser modes and collision-free composite keys, enforce architecture guards, and consolidate redundant unit assertions into filesystem, CLI, MCP, and producer-backed workflows. Preserve concurrent upstream boundary fixes and exclude legacy Objective-C class-name bookkeeping labels.
Validation: source/composition suites (3358 passing), focused canonical digest and MCP checks, typecheck/lint, Knip, formatting, architecture guards, and real Foundation archive and Apple legacy simulator CLI/MCP verification. No real Hopper, Ghidra, or IDA verification claim.
Fixes#1338.
Use canonical product identity for bundled command versions and keep build-cache fixtures aligned. Verified 10 focused tests, actual CLI installation/repair/uninstall scenarios and all 19 final-head CI checks.
Co-authored-by: Yi-111-a <97448247+Yi-111-a@users.noreply.github.com>
Reject omitted segment bounds, procedure classification and body facts, unresolved-call observations, dossier facets, and Ghidra parameter flow metadata. Providers emit explicit nulls for unsupported facets. Verify those unknowns in the real Hopper workflow.
BREAKING CHANGE: Provider analysis outputs must explicitly supply metadata previously repaired with defaults; unsupported nullable facets must be reported as null.
The generated skill rewrote `rea-agents@latest` to the version it ships with, so a pinned install no longer needs a local edit that `doctor --skill` reports as stale.
Co-Authored-By: OpenCode <opencode@opencode.ai>
BREAKING CHANGE: Objective-C attribute tokens now contain only name and value. Properties report nullable atomicity and readonly facts; class flags, ivar counts, and method requirement flags are nullable when unobserved.
* feat(setup): register OMP during setup
Add OMP (oh-my-pi) as a setup, doctor and uninstall client. Setup writes
a type: stdio entry to the user-level agent mcp.json that OMP reads,
following PI_CONFIG_DIR, an absolute PI_CODING_AGENT_DIR and the
OMP_PROFILE/PI_PROFILE named profile. It removes rea from OMP's
disabledServers denylist, which would otherwise hide the registration,
and doctor reports a listed registration as stale.
Closes#1257
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(setup): honor OMP's enabledServers allowlist in doctor
OMP's user enabledServers allowlist forces an entry with enabled: false
on, unless disabledServers also lists it. Doctor reported such a working
registration as stale. Also format the FAQ client list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(setup): keep OMP's allowlisted entry in update maintenance
rea update skipped an owned OMP entry with enabled: false even when
OMP's enabledServers allowlist runs it. Apply the same forced-enable rule
as doctor. Share the client-location environment reset across the client
tests instead of repeating it in each file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Remove forwarding wrappers and shadow aliases, migrate callers and verification scripts to their owners, and share one exhaustive semantic resource-bound projection.