Thread the existing resource scope through skill and client configuration reads. Keep failed-close handles owned, wait for admitted reads, and surface unresolved cleanup alongside doctor, uninstall and update results.
Validated focused setup/doctor/update and filesystem boundary checks, temporary-file hygiene, packaged setup/update/uninstall workflows, and static checks. No external provider installation was performed.
Serialize resolution with shutdown, retain the owned browser after close failures, and retry cleanup before another launch. Wire cleanup through the shared service and CLI/MCP lifecycles, preserving primary failures and completed native reports alongside cleanup diagnostics.
Separate the browser resolution workflow from lifecycle ownership. Validation: seven resolver source tests, eleven application tests, MCP shutdown retry, public CLI parity, and full static/architecture checks passed. Real Chromium behavior remains unverified.
Analyze exact selected sources in first-request order before unrelated
static scopes, preserving full artifact identity and byte verification.
Retain selection in CLI/MCP Evidence and summaries, with explicit unknowns
and partial coverage for unselected sources. Keep default full analysis.
Fixes#1848
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
* feat(native): admit raw binaries with caller-supplied architecture and entry
* fix(native): honor raw-binary preparation and entry identity
* fix(ghidra): stream raw snapshot attestation with cancellation
* fix(native): preserve and validate raw lifecycle entries
---------
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
* feat(harmony): project HarmonyOS package inventory evidence
First HarmonyOS increment from #1431: HAP, HSP, and App Pack roots are
classified through the hardened ZIP reader and projected into an
execution-free application graph with packaging-model hints, exact
component paths and hashes, App Pack children by path, runtime-family
hints, and path-based N-API bridge hypotheses. HarmonyOS .har stays
unclassified by suffix because .har also names HTTP Archive JSON.
Adds the project_harmony_application_graph tool (CLI and MCP), synthetic
composition coverage, a pinned real-package verify lane, and docs.
* refactor(domain): share application graph projection scaffolding
The HarmonyOS projection mirrors the Android and Apple projections by
design, which pushed jscpd duplication over its 2.5 percent budget.
Extract the identical pieces (inventory input schema, projected
component schema and occurrence flattening, bridge candidate schema
factory, coverage assembly, comparator, canonical digest) into
domain/mobileApplicationGraphProjection.ts and route all three
projections plus the composition fixtures through it. Duplication drops
from 2.52 to 2.49 percent with no behavior change: projection ids,
classifications, and limitations are byte-identical.
* fix(harmony): address review, stable app-pack roots, and rotated fixture
- rebased onto main; the shared projection scaffolding now keeps main's
nativeRuntimeConvention loop and the harmony runtime families adopt the
same react-native/flutter/unity path conventions
- the .app App Pack suffix is now a root-input rule only (verified ZIP
magic in classifyRootFormat and BinaryTargetResolver); nested .app ZIP
members inside other packages keep the generic zip classification, with
a regression test, so existing inventories do not change
- the signing limitation now states that an empty signing list does not
mean unsigned because packaging-tool signatures live in the ZIP signing
block, and the app-pack root rule is disclosed as suffix-based
- repinned the real-package fixture to the current VHome 2.6.14-beta asset
after the upstream deleted v5.0.111-beta and replaced the v2.6.14-beta
asset within hours; the pin records both observed digests
---------
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Setup run through bunx or bun x registered the bin inside bun's temporary
package cache. Detect bun's package-runner launch from npm_command=exec
with a bun user agent and register the pinned bunx launcher, wrapped in
cmd.exe on Windows like the npx launcher. Doctor, update maintenance and
uninstall recognize it as REA-owned, and setup's printed commands name
the runner that launched it.
Read the runner variables case-insensitively on Windows, where the CLI
environment snapshot upper-cases variable names and setup run through
npx also fell back to the cache path.
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
* feat(javascript): recover code-split bundles from multiple inputs
recover_javascript_sources accepted a single path, and
validateModuleSet bound every module's provenance to that one snapshot.
A code-split app (runtime + chunks, or an Electron main/preload/renderer
set) had to be recovered one file per call, and modules recovered alone
could not resolve imports across chunks: cross-chunk require(id)
references stayed as numeric ids with property reads.
Add an optional additional_paths input. The listed files are
concatenated, in order after path, into the single engine snapshot, so
one Wakaru run sees every module and cross-chunk imports resolve.
validateModuleSet's single-snapshot binding is unchanged. Module
provenance is attributed back to the input file its first extraction
range starts in, with byte ranges rebased to that file's own offsets;
a module whose ranges cross an input boundary keeps the concatenated
snapshot identity and offsets, recorded as an explicit limitation.
Single-path behavior is byte-for-byte unchanged (one segment,
offset 0).
Fixes#1605
* fix(javascript): preserve source identity in multi-input recovery
---------
Co-authored-by: JingHao-Leon <w15909130000@gmail.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Load application and Electron workflow implementations only when their commands execute. Keep command schemas and catalog registration eager, and extend the startup import boundary to cover the deferred services.
* fix(build): emit no runtime imports for type-only bindings
Under verbatimModuleSyntax, an import whose specifiers all carry inline
`type` modifiers compiles to `import {} from "..."`, a side-effect import
that still resolves and evaluates the module. 78 compiled modules carried
one, including `import {} from "playwright-core"` in the browser scenario
session, which loaded Playwright's module graph at MCP startup.
Use top-level `import type` for these bindings and enable oxlint's
typescript/no-import-type-side-effects rule so the pattern cannot return.
Refs #1685
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* perf(mcp): load Playwright when a scenario launches, not at startup
The browser scenario and Electron active providers are constructed before
the stdio server serves, and both bound Playwright's launchers at module
load. Resolve `chromium` and `_electron` from playwright-core when a
capture opens instead, as the web module resolver already does.
MCP startup now resolves 1,312 modules (4,902 resolutions) instead of
1,598 (6,076) before reading the first request, and no longer loads
playwright-core. Provider construction, the tool catalog, and capability
inventory are unchanged.
A boundary test spawns the stdio server, initializes, lists tools, and
asserts playwright-core and isomorphic-git were not resolved; the CLI
probe now exercises the real launch path to prove detection.
Closes#1685
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* feat(evidence): discover retained records without full payloads
* fix(evidence): guide oversized results to retained discovery
* style(tests): format retained discovery recovery assertion
Keep the optional address description visible to incur and describe the actual
bundle plist default and absolute-path support. Extend the existing command
help sweep instead of traversing the inventory a second time.
Refs: #1418
Co-authored-by: Fazmin <fazmin.nizam@gmail.com>
Require a caller-owned artifact resource scope for source traversal and Git metadata reads. Preserve cancellation, filesystem reasons, partial entries and bytes, and cleanup observations through import and the CLI. Transfer exact failed file owners at regular-file admission and close boundaries, including multiple failures encountered by Git reference resolution.
Validation: 169 focused tests passed across 26 files; two Windows-only cases skipped. Build, typecheck, lint, formatting, knip, architecture guards, discovery and docs checks passed.
BREAKING CHANGE: Reference source readers and imports require an ArtifactResourceScope. VCS metadata reads return Result, and CLI import failures include observed details and partial evidence.
Require an ArtifactResourceScope for web script exports and share its lifetime with CLI or MCP shutdown. Retain setup-failed output trees in firmware and Wakaru providers. Preserve completed publications when descriptor cleanup fails, returning the full result after a successful retry or as a partial observation while cleanup remains unresolved.
Keep failed reader, root descriptor, and output-tree cleanup with the caller. Drain admitted work before close, retry the same retained owners, and block new resource work while cleanup is incomplete. Preserve primary failures and complete inventory observations.
Thread ownership through JavaScript reconstruction, the CLI's one-shot scope, MCP server shutdown, verifier scripts, and test fixtures. Remove redundant ownership flags and the unused validated test wrapper.
Validate with 850 passing focused tests across 90 suites (two skipped), targeted classification and cleanup retries, static and unused-code checks, and real macOS CLI/MCP directory, ZIP, and DMG workflows. Native Windows and deep-analysis providers were not verified.
BREAKING CHANGE: Direct artifact inventory/extraction and JavaScript analysis APIs require an explicit caller-owned ArtifactResourceScope. CLI and MCP input contracts are unchanged.
* feat(apktool): decode Android resource tables through a caller-supplied launcher
Add an Apktool family with two operations over the caller's apktool
launcher (REA_APKTOOL_COMMAND, absolute, or apktool on PATH):
- inspect_apktool_client: resolved launcher, selection source, and
version; decodes nothing.
- decode_android_resources: apktool d --no-src in a provider-owned
workspace that is removed before the result returns. Projects the
decoded AndroidManifest.xml (bounded at 512 KiB), apktool.yml version
and SDK facts exactly as printed, string resources verbatim (default or
one locale, bounded at 2000 entries, nested-markup entries counted as
unparsed), available string locales, and the decoded file count with a
hard cap. The target APK is digested with SHA-256 before decoding so
Evidence binds the observation to the exact input.
Smali production is skipped by design: Java-source recovery belongs to
the JADX family. Workspace cleanup happens before results return; an
unremovable workspace is named in the limitations instead of abandoned.
Verified against apktool 2.7.0-dirty (Debian packaging) on Linux with
OpenJDK 25 against a signed aapt2-built probe APK with two resource
locales: launcher version, on-disk digest agreement, metadata projection,
manifest package agreement, and both string tables (default and de).
Parser goldens come from the same decode. READMEs carry the new
'Android resources' row in every supported language.
* fix(apktool): own snapshots and bound decoded resource reads
* docs(apktool): describe owned resources and bounded projection
---------
Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
* 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(electron): resolve pages served from inside app.asar
Packaged Electron applications load their renderer pages from file URLs
inside app.asar. The host filesystem cannot stat those paths, so
list_electron_targets excluded every such page as unsupported_url and
inspect_electron_page could not select it.
Resolve these URLs the way Electron's file protocol does: the first .asar
path component that is a regular file is the archive, and the remainder
must name a regular file in its header. Directories, links, and missing
members stay rejected. Parsed headers are cached by archive identity.
* fix(artifacts): extract and explain rewritten ASAR unpacked companions
Packaging tools commonly sign or strip .asar.unpacked native binaries after
writing the archive header, so their declared hashes no longer match.
analyze_javascript_application already accepts integrity_policy, but
extract_artifact did not, and inspect_artifact and extract_artifact still
told callers to "get a fresh copy", which cannot help for a shipped app.
- Accept integrity_policy on extract_artifact (MCP and CLI). The default
still fails closed; record-and-continue writes the observed bytes and
returns the extracted files' integrity_contradictions records.
- Name the unpacked entry and the post-packaging cause in integrity
failures, and point every operation that accepts integrity_policy at
record-and-continue.
- Report an active unpacked entry whose companion file is absent as
unavailable with its logical path instead of a format failure.
- Share one integrity_policy schema across the inventory, extraction, and
JavaScript application inputs.
* fix(electron): bound ASAR headers before allocation
---------
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>
`--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>
compare-web-captures and compare-web-screenshots parsed their arguments as
inline JSON only, unlike every other JSON-input command. Screenshot
artifacts and scenario captures embed base64 PNG bytes, so a typical
viewport screenshot exceeds the command-line length limit (128 KiB per
argument on Linux, 1 MiB total on macOS) and could not be compared from
the CLI at all, while MCP accepts it. A file path was reported as
malformed JSON, and screenshot schema failures returned no issues.
Each argument now accepts inline JSON or a JSON file path through
parseCliJsonInput; file failures keep its path diagnostics, malformed
inline JSON keeps the field issue, and screenshot validation reports
projected schema issues. The tests share one CLI JSON process fixture.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Incur's `alias` map registers one-letter short flags and already accepts
kebab-case spellings of camelCase options. Twenty options registered their
kebab-case long name as an "alias", so help and completions advertised
flags such as `-case-sensitive` and `-relative-path` that the parser reads
as stacked short flags and rejects with "Unknown flag: -c".
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Route ordinary CLI results through the bounded JSON writer after command registration, including managed member inspection. Remove JavaScript-specific output plumbing while preserving filters, envelopes, cancellation, and failure exits.
Measure formatted UTF-16 expansion before Incur token counting and return resource_constraint above the runtime string limit, with recovery guidance.
Validate output above the real V8 string limit by SHA-256 and exercise the compiled managed provider. Clean-worktree validation: npm run check; 76 focused tests passed, with 2 optional-provider skips; test discovery passed.
Fixes#1371.
Remove forwarding wrappers and shadow aliases, migrate callers and verification scripts to their owners, and share one exhaustive semantic resource-bound projection.
Deliver complete Evidence directly through MCP with required nullable analysis profiles and immutable per-server delivery settings. Bind selected environments at construction and require typed cleanup outcomes with retained retry ownership.
Remove test-only routing, duplicate session and snapshot metadata, producer-field repairs, and ambiguous provider arguments. Separate artifact byte identity from occurrence classification and retain typed source-map and partial native facts across CLI, MCP, and verifier consumers.
BREAKING CHANGE: obsolete Evidence envelopes, session aliases, incomplete snapshots, and missing normalized producer facts are no longer accepted.
Propagate CLI interrupts to capture and interrupt post-exit settlement
without cancelling owned-resource cleanup or discarding prior observations.
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Add explicit summary, facet, item and paged views of retained analysis Evidence without repeating analysis. Preserve captured observations, graph validation, artifact identity, coverage and complete default results.
Fixes#1050
Verified with focused source, CLI, pinned-SDK schema and MCP tests, serial static checks, and one complete native Windows Notion ASAR workflow. Real Hopper/Ghidra verification was not performed for this provider-independent projection change.
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Incur derives `--schema`, the `--llms` manifests, and help synopses from
Zod's output view, where a defaulted field always has a value, so every
defaulted argument and option was listed as required even though the CLI
accepts its omission. Wrap each field that fills an omitted value as
optional after registration, keeping its default, constraints, metadata,
and parsed value.
Fixes#1169
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
`rea analyze PATH` routes a JavaScript directory or ASAR to the same
static analysis as `rea analyze-javascript-application`, but it passed
no signal and was not wrapped in withCommandCancellation. On SIGINT the
process was killed with no output (signal SIGINT, empty stdout).
The dedicated command returns a typed `cancelled` result and exits 130.
The #1098 review raised this route.
Decide the route first. A JavaScript target now runs exactly like the
dedicated command: cancellation wraps logging, so the cancelled exit
code is not replaced by the logged failure status. The binary route is
unchanged and keeps its own SIGINT handling in runDirectAnalysis.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Retain complete authenticated application Evidence when the repeated MCP representation exceeds the default receive frame or Node string limit. Return a typed transport constraint, keep useful followup queries available, and stream full canonical bundles to atomic destinations.
Verify complete Notion and Obsidian workflows on Linux and native Windows, full CLI/Evidence parity, and real large Chrome screenshot recovery. Preserve complete success contracts and caller-selected evidence paths.
Refs #1065, #1053.
* feat(native): inspect recorded crashes through pwntools and pwndbg
* fix(native): bind core note semantics to raw owner bytes
* fix(native): validate recorded core ABI and evidence scalars
* fix(native): require complete recorded note interpretations
* fix(native): bind physical core notes to original headers
main now carries #1037 (skill version 30, reworded native binary row):
- README_ja/ar/ko/zh: take main's tables and count
trace_dylib_resolution in the artifact graph row (5 -> 6).
- Skill: move to version 31.
- Regenerate the product catalog, conformance manifest, skill digest and
package metadata (137 tools).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main now carries #964 (skill version 29, macOS native row 7 -> 8):
- README_ja/ar/ko/zh: take main's tables and count
trace_dylib_resolution in the artifact graph row (5 -> 6).
- Skill: move to version 30.
- Regenerate the product catalog, conformance manifest, skill digest and
package metadata (136 tools).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>