Commit Graph
4150 Commits
Author SHA1 Message Date
all-black-493 62c8b3da1b feat(browser): attach passive tools to browsers without HTTP discovery (#2346)
* feat(browser): attach passive tools to browsers without HTTP discovery

Accept a literal loopback browser WebSocket,
ws://127.0.0.1:PORT/devtools/browser/ID, as the cdp_endpoint of the six
passive browser tools. Discovery then reads Browser.getVersion and
Target.getTargets over that socket, and the target session adopts the
same socket, so a browser that asks for consent per connection prompts
once per call.

The socket identifier gates access, so Evidence records the endpoint as
ws://127.0.0.1:PORT/devtools/browser/[REDACTED], and runtime
reconciliation accepts that recorded form. HTTP endpoints and their
Evidence are unchanged. Electron, web runtime, scenario and Inspector
endpoints stay HTTP-only.

Refs #2288

* test(browser): match browser-socket captures against HTTP discovery

Check in the real Chrome lane that DevToolsActivePort names the same
browser socket as /json/version, and that inspecting the selected page
through that socket leaves DOM structure and scripts unchanged compared
with an inspection through HTTP discovery.

Refs #2288

* fix(browser): bound browser-socket handshake and report discovery timeouts

Run the browser-socket WebSocket handshake and both discovery commands
under one discovery deadline, so a port that accepts the connection but
never completes the upgrade times out instead of waiting forever.

Report a reached deadline as a timeout without carrying the internal
abort as its cause, so CLI and MCP project provider_timeout rather than
cancelled. Caller cancellation is still reported as cancelled.

Refs #2288
2026-10-14 00:36:37 +08:00
ShitK 0c9ee56c2f fix(native): accept declared facts in dispatch name inventory (#2906) 2026-10-14 00:34:06 +08:00
ShitK 501c5d45fe fix(managed): share native verification input diagnostics (#2901) 2026-10-14 00:33:14 +08:00
df3d96da80 fix: repair the static-check failures on the default branch (#2895)
* fix: repair the static-check failures on the default branch

The default branch fails its own required `Static checks` job three ways, so
every pull request reports that job as failed regardless of its own change.

- `npm run format:check` reports `src/domain/functionComparison.test.ts` and
  `src/ida/IdaOperationRunner.ts`.
- `npm run lint` reports a duplicate `import { join } from "node:path"` in
  `tests/boundary/mcp/ghidraInventoryMcp.test.ts` (lines 4 and 17).
- `npm run typecheck` reports `format: "devin"` missing from the client format
  union in `src/application/SupportedClients.ts`, and an unchecked index in
  `tests/boundary/cli/clientProfileLifecycle.test.ts`, whose pair array is
  inferred as `string[][]`.

Apply the pinned formatter, drop the duplicate import, list the `"devin"` format
that its own definition already uses, and mark the pair array `as const`.

Validation: `npm run check:fast` and `npm run format:check` pass.

* fix(setup): keep Devin on the JSON configuration dialect

---------

Co-authored-by: 吴佳浩 <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-14 00:31:27 +08:00
7e3a198638 fix(javascript): keep logical assignment results uncertain for unknown values (#2788)
* fix(javascript): keep logical assignment results uncertain for unknown values

* test(javascript): cover exact uninitialized logical assignments

Source inspection and targeted formatting only. Tests, builds, lint, typechecks and provider workloads were not run at the user's explicit request.

---------

Co-authored-by: Ganesh2325 <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-14 00:06:45 +08:00
hhangandhhang 72b9ab4af1 fix(javascript): retain configuration reads before member access (#2756)
Squash merge of https://github.com/morluto/rea/pull/2756.

Original pull request submitted by @xu91102.

Co-authored-by: hhang <[email protected]>
2026-10-13 23:59:49 +08:00
d4f0c5e664 fix(cli): start on Windows when USERPROFILE is empty (#2345)
* fix(cli): start on Windows when USERPROFILE is empty

Node's Windows home lookup throws ERR_SYSTEM_ERROR (uv_os_homedir ENOENT)
for an empty USERPROFILE instead of consulting the account profile. Incur
resolves the home while it is imported, so every command, including
`rea --version`, stopped with a raw stack trace before REA ran.

Treat the empty selection as unset in the launcher, before any runtime
import, and cover startup with a compiled-CLI regression.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(process): report no remaining time after a provider deadline fires

Node timers can fire while performance.now() is still a fraction of a
millisecond short of the monotonic deadline. ProviderStartupDeadline then
reported interruption "timeout" and an aborted signal while remainingMs()
returned ceil(0.x) = 1, so polling loops guarded by remainingMs() > 0
(Hopper and Ghidra startup) could run past an elapsed deadline, and the
real-timer test "aborts a bounded wait when its real monotonic deadline
expires" failed intermittently in CI (expected 1 to be 0).

Once the deadline's own timer has classified a timeout, report zero
remaining time. A deterministic regression test fires the timer with the
monotonic clock 0.4 ms short of the deadline.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: morluto <[email protected]>
Co-authored-by: Kaoru0822 <[email protected]>
2026-10-13 23:53:35 +08:00
Riley Gramlich 3f80b75708 fix(source-maps): keep sources when sourcesContent length differs (#2873)
ECMA-426 DecodeSourceMapSources reads a content slot only while its index
is within sourcesContent, so a shorter array leaves trailing sources
without content and a longer array adds no sources. Local application
analysis and browser collection rejected any length mismatch and dropped
every original from the map.

The content helper now checks only entry types. Browser collection drops
its separate check because the leaf schema already validates every
supplied entry, and the raw records are still budgeted before parsing.

Fixes #2821
2026-10-13 23:52:47 +08:00
吴佳浩Albenand吴佳浩 855ed9689e fix(application): preserve a cancellation that races a completed provider run (#2710)
Squash merge of https://github.com/morluto/rea/pull/2710.

Original pull request submitted by @XiaoBinGan.

Co-authored-by: 吴佳浩 <[email protected]>
2026-10-13 23:51:44 +08:00
吴佳浩Albenand吴佳浩 59298923a5 fix(apktool): read the resource locale grammar from its owner (#2738)
Squash merge of https://github.com/morluto/rea/pull/2738.

Original pull request submitted by @XiaoBinGan.

Co-authored-by: 吴佳浩 <[email protected]>
2026-10-13 23:51:30 +08:00
Royceandmorluto af782dd5f5 fix(setup): treat empty DSH_HOME as unset (#2686)
* fix(setup): treat empty DSH_HOME as unset (#2666)

The released `@deepseek-ai/dsh-home-paths` package explicitly treats an
empty or whitespace-only `DSH_HOME` as unset and selects the default
Harness home patch. `dshHomeDirectory` previously used nullish coalescing
(`env.DSH_HOME ?? join(home, ".dsh")`), so an empty override flowed
straight through `join(..., "cordis.patch.yml")` and produced a
cwd-relative `cordis.patch.yml` outside the client-selected home.

Treat empty and whitespace-only overrides as unset, matching the sibling
OpenCode override resolver and the released DSH resolver. The patch now
lands at `$DSH_HOME/cordis.patch.yml` for explicit overrides, the default
`~/.dsh/cordis.patch.yml` for empty/unset, and trimmed whitespace for
padded overrides.

Adds `src/application/SupportedClients.test.ts` covering the empty,
whitespace-only, unset, padded, and explicit cases via the public
`supportedClients(...)` entrypoint. Fixes #2666.

* test(setup): remove superseded DSH path unit coverage

---------

Co-authored-by: morluto <[email protected]>
2026-10-13 23:51:28 +08:00
d86d29c411 fix(mcp): keep advertised inputs within client reference budgets (#1749)
Squash merge of https://github.com/morluto/rea/pull/1749.

Co-authored-by: akushonkamen <[email protected]>
Co-authored-by: GLM <[email protected]>
2026-10-13 23:49:53 +08:00
TonyWuandTonyWu 77e71d55ec fix(native): name numeric Mach-O build-version platforms and tools (#2065)
Squash merge of https://github.com/morluto/rea/pull/2065.

Co-authored-by: TonyWu <[email protected]>
2026-10-13 23:49:37 +08:00
SII-YDDandmorluto 168bfe5060 fix(target): probe WASM before inferred database routing (#2007)
* fix(target): probe WASM before inferred database routing

* test(wasm): execute recovery arguments from native refusal

* test(ci): repair fixture alignment and share MCP assertions

---------

Co-authored-by: morluto <[email protected]>
2026-10-13 23:49:33 +08:00
JinandClaude Opus 5.5 554ea7611e fix(adb): keep the device's refusal when a package change exits nonzero (#2344)
Squash merge of https://github.com/morluto/rea/pull/2344.

Co-authored-by: Hui <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-13 23:49:20 +08:00
Thang LuuandThang Luu 911894d758 feat(wasm): compare retained core-module interfaces (#2464)
Squash merge of https://github.com/morluto/rea/pull/2464.

Co-authored-by: Thang Luu <[email protected]>
2026-10-13 23:49:04 +08:00
pablodiazjorgeandpablodiazjorge 75e7965dc3 docs(nativeaot): document the verified Windows-host parser route (#2497)
Squash merge of https://github.com/morluto/rea/pull/2497.

Co-authored-by: pablodiazjorge <[email protected]>
2026-10-13 23:48:41 +08:00
The one -NiuandNIU-123370 522b9927c8 feat(recorded-crash): decode AArch64 core register notes (#2505)
Squash merge of https://github.com/morluto/rea/pull/2505.

Co-authored-by: NIU-123370 <[email protected]>
2026-10-13 23:48:24 +08:00
2b98fc5f51 fix(cli): reject empty analyze and artifact target paths (#2687)
Squash merge of https://github.com/morluto/rea/pull/2687.

Co-authored-by: LouisChen <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-13 23:48:09 +08:00
The one -NiuandNIU-123370 8b1549a264 test: share repeated boundary preambles to restore the jscpd gate (#2691)
Squash merge of https://github.com/morluto/rea/pull/2691.

Co-authored-by: NIU-123370 <[email protected]>
2026-10-13 23:47:55 +08:00
The one -NiuandNIU-123370 782cc3b060 refactor(process): give the prlimit producer budget one owner (#2698)
Squash merge of https://github.com/morluto/rea/pull/2698.

Co-authored-by: NIU-123370 <[email protected]>
2026-10-13 23:47:41 +08:00
f825c869d6 fix(artifacts): bound expanded ASAR listing before allocation (#2724)
Squash merge of https://github.com/morluto/rea/pull/2724.

Co-authored-by: chAngE <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-13 23:47:18 +08:00
LouisChenandLouisChen 9240a4e9ac fix(javascript): preserve asterisks in block source-map URLs (#2728)
Squash merge of https://github.com/morluto/rea/pull/2728.

Co-authored-by: LouisChen <[email protected]>
2026-10-13 23:47:03 +08:00
Jeremy Levartovsky ba06d9ec52 fix(setup): keep a Cordis operation's own fields when uninstall empties it (#2730)
Squash merge of https://github.com/morluto/rea/pull/2730.

Co-authored-by: JayOfTheKeyboard <[email protected]>
2026-10-13 23:46:46 +08:00
Feng af7638fa9d fix(session): preserve investigation records after failed target opens (#2754)
Squash merge of https://github.com/morluto/rea/pull/2754.

Co-authored-by: Adkid-Zephyr <[email protected]>
2026-10-13 23:46:23 +08:00
Iven KooandIvenKooLab 48b90fbaa4 fix(native): preserve unresolved calls in untyped route fallback (#2757)
Squash merge of https://github.com/morluto/rea/pull/2757.

Co-authored-by: IvenKooLab <[email protected]>
2026-10-13 23:46:02 +08:00
Kaoru0822andClaude Opus 5.5 c580ba940a fix(browser): treat an unusable cache list as incomplete storage coverage (#2762)
Squash merge of https://github.com/morluto/rea/pull/2762.

Co-authored-by: Kaoru0822 <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-13 23:43:11 +08:00
2a78763e20 feat(native): search analyzed memory for masked byte patterns (#2341)
* feat(native): search analyzed memory for masked byte patterns

The diff adds search_bytes to the CLI, the shared MCP contract, Ghidra
inventory, and the headless bridge, and advertises the same operation on
Hopper as unavailable until that provider is verified. Patterns are
hexadecimal byte pairs with optional ?? wildcards and an optional
equal-length bit mask; the TypeScript boundary and the bridge both
require a nonempty pattern, equal lengths, and at least one constrained
bit. Ghidra walks initialized blocks in address order within inclusive
bounds, keeps overlapping matches inside a single block, and returns
each hit with its segment, unique source file offset, and containing
procedure, continuing through a cursor bound to the target, profile,
pattern, mask, and bounds. Each page reports the inclusive ranges
examined and the skipped uninitialized blocks; cancellation returns a
typed error and discards the active Ghidra database.
address_to_file_offset now uses the same unique-offset helper, which
rejects a mapping that is missing, ambiguous, or larger than a safe
integer.

* fix(native): limit unbounded byte search to loaded memory

Without start or end, search_bytes walked every Ghidra block, including
non-loaded file parts such as .symtab and overlay blocks, which the docs
call out of scope. Unbounded searches now skip those blocks and list them
in searched.skipped_not_loaded; explicit bounds in their address space
still search them. Document that a match must end at or before end.

* fix(native): preserve implicit address spaces in range consumers

* fix(native): reject present malformed byte search state

---------

Co-authored-by: Matt Van Horn <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-13 23:41:45 +08:00
70611713e1 fix(targets): compare the Info.plist bplist prefix without ASCII folding (#2100)
* fix(targets): compare the Info.plist bplist prefix without ASCII folding

The six-byte prefix check used an encoding that maps high-bit bytes onto bplist, so a non-binary property list could be sent to the binary decoder.

Co-authored-by: Cursor <[email protected]>

* fix(targets): satisfy the strict index check in the plist prefix test

Co-authored-by: Cursor <[email protected]>

---------

Co-authored-by: Cursor <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-13 23:37:45 +08:00
43e33cd49e fix(artifacts): compare plist and NIB signatures without ASCII folding (#2098)
* fix(artifacts): compare plist and NIB signatures without ASCII folding

Buffer.toString("ascii") drops the high bit, so a non-plist prefix could be decoded as bplist00 or NIBArchive and sent to the binary decoder.

Co-authored-by: Cursor <[email protected]>

* fix(artifacts): satisfy the strict index check in the signature test

Co-authored-by: Cursor <[email protected]>

* fix(artifacts): remove superseded signature regression causing CI failure

---------

Co-authored-by: Cursor <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-13 23:37:31 +08:00
Tony Yuandmorluto efc491ab45 feat(setup): add Kimi Code client support (#2744)
* feat(setup): add Kimi Code client support

Registers rea in ~/.kimi-code/mcp.json (or $KIMI_CODE_HOME/mcp.json), preserving unrelated settings with a .rea.backup; registration is command-based stdio with no type field, startupTimeoutMs 30000 and toolTimeoutMs 120000 from MCP_STARTUP_POLICY.
Strict JSON parsing: empty or whitespace-only files initialize; malformed JSON is rejected untouched with no backup; explicit transport other than stdio reports invalid.
Bundled skill uses the shared ~/.agents/skills destination that Kimi Code discovers, installed and verified through the shared-skill flow.
Validated by 19 Kimi-specific tests, 260 adjacent-client regressions passing, check:fast and docs:check, and real-client verification on Kimi Code 0.40.1 (173 tools discovered, real mcp__rea__analyze_javascript_application call succeeded).

* fix(setup): preserve Kimi tool filters and strict JSON coverage

---------

Co-authored-by: morluto <[email protected]>
2026-10-13 23:36:54 +08:00
hhangandhhang b19f9e4d2d fix(javascript): keep spread child argv counts unknown (#2748)
* fix(javascript): keep spread child argv counts unknown

* test(javascript): own runtime controls and tighten evidence assertions

* test(apple): keep dyld slice regression portable

---------

Co-authored-by: hhang <[email protected]>
2026-10-13 23:36:35 +08:00
af142f656c fix(mcp): report references a provider truncated in trace_feature (#2348)
* test(mcp): expect trace_feature to report references the provider truncated

A provider that reports a capped xrefs read makes the trace truncated with a residual unknown for that target. An explicit complete report and a provider that reports nothing leave the trace as before.

* fix(mcp): report references a provider truncated in trace_feature

Executions gain an optional flag for a capped xrefs read, set by the IDA adapter from the upstream cap. trace_feature marks the trace truncated with a residual unknown for that target only when the provider reports a truncation; a provider that reports nothing keeps its previous result. The trace_feature workflow profile is revised so earlier results are not replayed.

* refactor(ida): report reference truncation whenever the runner observed an xrefs cap

* test(mcp): cover session forwarding, per-target state, native reports and failures of the trace coverage

* test(mcp): format the session forwarding test

* test(process): format processCaptureLifecycle.test.ts after the merge

* test(ida): declare the alignment each synthetic universal slice offset satisfies

* fix(process): report no remaining time after a provider deadline fires

Node timers can fire while performance.now() is still a fraction of a
millisecond short of the monotonic deadline. ProviderStartupDeadline then
reported interruption "timeout" and an aborted signal while remainingMs()
returned ceil(0.x) = 1, so polling loops guarded by remainingMs() > 0
(Hopper and Ghidra startup) could run past an elapsed deadline, and the
real-timer test "aborts a bounded wait when its real monotonic deadline
expires" failed intermittently in CI (expected 1 to be 0).

Once the deadline's own timer has classified a timeout, report zero
remaining time. A deterministic regression test fires the timer with the
monotonic clock 0.4 ms short of the deadline.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
(cherry picked from commit dfdaa0ca74)

* fix(process): keep monotonic deadline ownership after merge

---------

Co-authored-by: morluto <[email protected]>
Co-authored-by: Kaoru0822 <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-13 23:35:21 +08:00
Huamnanxandmorluto ffd8c9c03d test(evaluation): grade managed agent fixture facts (#1924)
* test(evaluation): grade managed agent fixture facts

* test(evaluation): cover distinct managed artifact deliveries

* fix(evaluation): require unfiltered managed type inventories

* fix(evaluation): preserve selected entry point grounding

---------

Co-authored-by: morluto <[email protected]>
2026-10-13 23:34:17 +08:00
CindyGestandmorluto 7dcd23c005 fix(setup): separate host support and stop skill checks after drift (#2073)
* fix(host): separate REA host support from Hopper installer targets

LinuxDistribution.supported carried two meanings at once: that the host runs
REA, and that the automated Hopper installer is tested on it. The doctor read
the first meaning from the second, so Debian-derived hosts such as Kali
reported unsupported_host while their providers worked normally.

Rename the field to hopperSetupSupported, which only the Hopper installer and
setup planning consume, and derive host support from the package family
through supportsReaHost(). Any distribution with a recognized apt, dnf, or
pacman family is now a REA host. The tested Hopper installer list is
unchanged, so Debian and Kali keep falling back to configuring an existing
provider instead of downloading an untested package.

Verified on Kali 2026.3 (Debian testing, x86_64): rea doctor reports a healthy
environment with Ghidra 12.1.4, and analyze_function decompiles an x86_64 ELF
through the MCP server. npm run check, npm run docs:check, and the application
and Ghidra suites pass. No Hopper or IDA host workflow was exercised.

* fix(setup): stop skill checks after first drift

---------

Co-authored-by: morluto <[email protected]>
2026-10-13 23:33:54 +08:00
ed93abed02 fix(cli): label each uninstall skill root by its client (#2197)
* fix(cli): label each uninstall skill root by its client

rea uninstall reported every managed skill destination under the
shared "skill" label (with only Claude Code special-cased), so a
retained or failed directory could not be told apart from the others.

Use the destination's client identifier so the aggregated detail names
each root: "shared: retained (...)", "claude_code: removed (...)",
"antigravity: retained (...)". Retained and failed entries now point to
the specific directory that needs attention.

Fixes #2111

Co-Authored-By: Claude Fable 5 <[email protected]>

* test(cli): align skill summary assertions with client and path labels

---------

Co-authored-by: wjl8636 <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-13 23:32:31 +08:00
Rohit Ghumareandmorluto d005bd5dcd fix(javascript): preserve CommonJS lookup and analysis provenance (#2306)
* fix(javascript): preserve CommonJS directory and ancestor lookup

* test(apple): bound cold archive fixture compilation

* test(release): scope preflight schema to selected jobs

* fix(javascript): retain requested analysis limits in Evidence

---------

Co-authored-by: morluto <[email protected]>
2026-10-13 23:31:30 +08:00
Lucienandmorluto 688defca0f fix(comparison): recheck historical calls-only changes (#2223)
* fix(comparison): preserve incomplete function call evidence

Keep missing, unknown, partial and unresolved call relationships unknown in function comparisons and reconstruction claims. Aggregate IDA caller and callee coverage without overwriting uncertainty.

Validate with 144 focused tests, typecheck/lint, docs checks and test discovery. Real providers were not verified; the full headless IDA session suite requires unavailable Windows native controls.

* fix(comparison): recheck historical calls-only changes

---------

Co-authored-by: morluto <[email protected]>
2026-10-13 23:30:31 +08:00
Lucienandmorluto 3c39a3f536 test(adb): isolate cross-platform activity launch regressions (#2226)
* fix(adb): reject timed-out activity launches and retain observations

* test(adb): isolate cross-platform activity launch regressions

---------

Co-authored-by: morluto <[email protected]>
2026-10-13 23:30:18 +08:00
xingzhou e6c6fdd21a fix(browser): preserve script-specific parser uncertainty (#2858) 2026-10-13 23:22:59 +08:00
xingzhou 40e94aeb9d fix(browser): preserve distinct WebMCP declaration metadata (#2854)
* fix(browser): preserve distinct WebMCP declaration metadata

* test(browser): retain the first equivalent declaration location
2026-10-13 23:19:37 +08:00
Shubham AhujaandClaude Opus 5.5 3e7c630223 fix(mcp): count the error flag in error result budgets (#2848)
Error results reach the wire as text plus `isError: true`, but the
text-only envelope omitted the flag. An error up to 15 bytes above the
result budget passed both the delivery and transport checks and was sent
as the original diagnostic instead of taking the oversized-error recovery
path.

Rename the error representation to "error-text" and size its envelope
with the flag, so ToolResultDelivery and the error transport share the
complete delivered shape. Successful structured results are unchanged.

Fixes #2557

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-13 23:06:55 +08:00
204a6f3f20 fix(ghidra): import HashMap in the bridge script (#2844)
8823c55b0 added a HashMap use without its import, so Ghidra could not
compile ReaGhidraBridge.java and every Ghidra-backed operation exited
before bridge startup.

Co-authored-by: SeokMyungSeop <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-13 22:57:45 +08:00
yasshmittalandClaude Opus 5.5 e13da084e7 fix(apple): exclude AppleDouble sidecars from IPA components (#2838)
* fix(apple): exclude AppleDouble sidecars from IPA components

IPA projection returned every inventoried component before the AppleDouble
sidecar filter applied to directory, ZIP and DMG roots, so ._* and
__MACOSX/ metadata appeared as native libraries and frameworks while the
result reported that sidecars are excluded. Apply the sidecar exclusion
first for every root format; IPA still keeps non-sidecar components
outside Payload/.

Fixes #2546

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* test(apple): exercise the __MACOSX exclusion with a non-dotfile name

The IPA fixture's __MACOSX entry also started with "._", so the AppleDouble
filename rule excluded it and a broken __MACOSX check would go unnoticed.
Use a library name that only the __MACOSX rule excludes; the native
library assertion now fails if that rule regresses.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-13 22:55:21 +08:00
Dragolone 94072364c7 fix(sqlite): keep triggers whose declaration spells the table in another case (#2807)
* fix(sqlite): keep triggers whose declaration spells the table in another case

SQLite stores a trigger's target in sqlite_schema.tbl_name exactly as
written in CREATE TRIGGER and resolves it by ASCII case folding, while an
index stores the table's own name. The selected_table scope filtered
tbl_name with COLLATE BINARY, so a trigger declared ON users for table
Users was omitted while the schema still reported complete. Match
dependents with COLLATE NOCASE, and report each trigger's table as the
stored table or view name so the selected-table contract still holds.

* fix(sqlite): refuse an inexact table before the case-folded schema scan

With the NOCASE expansion, a selection such as users for table Users
expanded the stored table's declarations before readRows reported the
missing exact name, so large trigger definitions could surface as an
output-limit failure instead of the selection error. Check the exact
table name against PRAGMA table_list first and share the selection
failure with readRows.

* fix(sqlite): fold dependent names only for a row-selectable table

An exact view, virtual or possible shadow table passed the exact-name
guard, so the NOCASE scan could still expand a differently cased trigger
past the reply budget before readRows refused the selection. Fold case
only when the selection is an ordinary table that is not a possible
shadow table, and keep the exact filter otherwise so every refused
selection fails as it did before the case-folding change.

* fix(sqlite): resolve trigger tables without folding unrelated names

The stored-name lookup case-folded every PRAGMA table_list name up front,
so a selected-table inspection of a tiny table paid for large unrelated
identifiers. A selected-table scan only returns the selected table's
dependents, so report the selected name directly; other scopes use an
exact stored name when one matches and fold the stored names once, only
when a trigger spells its target differently.

* perf(sqlite): fold each table name once when matching shadow parents

The extracted shadow-parent helper folded the table name inside the find
callback, once per unresolved virtual table, and the selected table was
checked both before and during the schema scan. Fold the name once per
call as before, and reuse the selected table's result in the scan.
2026-10-13 22:37:47 +08:00
xin zhuangandmorluto e103a89889 fix(artifacts): preserve NIB key and class name identity (#2109)
Co-authored-by: morluto <[email protected]>
2026-10-13 22:36:06 +08:00
The one -Niuandmorluto edd9939879 fix(browser): give the DevToolsActivePort wait one deadline owner (#2265)
* Single owner for the Chrome DevToolsActivePort startup deadline

Cold Chrome startup tolerance was spelled three ways for one wait: the helper
fell back to 15,000 ms, the runtime fixture lifecycle passed a literal 60,000,
and the real-browser verifier kept a local 60,000 constant. A per-caller literal
quietly changes how long a lane tolerates a cold browser before it fails, and
the failure reported only elapsed_ms, so a reader could not see which ceiling
was hit.

Export BROWSER_DEVTOOLS_STARTUP_TIMEOUT_MS as the owner, use it for the helper
fallback and both call sites, and report startup_timeout_ms in
BrowserStartupError. A source guard keeps callers from restating the number.

* Pin the DevToolsActivePort deadline guard to the startup call argument

---------

Co-authored-by: morluto <[email protected]>
2026-10-13 22:35:45 +08:00
Vinícius Andradeandmorluto 1e38a038c6 fix(process): release handles and close worker on incomplete cleanup (#2321)
* fix(process): unreference handles on incomplete provider process stop

Signed-off-by: Vinícius DS Andrade <[email protected]>

* fix(javascript): close worker and release handles on incomplete cleanup

Signed-off-by: Vinícius DS Andrade <[email protected]>

* fix(javascript): defer worker stdin close until incomplete cleanup

Signed-off-by: Vinícius DS Andrade <[email protected]>

* test(javascript): assert cleanup error instance on inspection uncertainty

Signed-off-by: Vinícius DS Andrade <[email protected]>

---------

Signed-off-by: Vinícius DS Andrade <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-13 22:34:54 +08:00
morluto 6e25cc3c76 fix(tests): clear lint and typecheck errors on main
Split two over-long test functions into module-level helpers
(max-lines-per-function): IdaSessionClient transport cases, IDA provider
composition, and function comparison identity cases keep their names and
assertions.

Also fix three typecheck errors: default omitted
direct_invokes_exhaustive to null so the result schema stays JsonValue
compatible, parse the ghidra dossier before spreading it, and delete the
optional beforeCall hook instead of assigning undefined under
exactOptionalPropertyTypes.
2026-10-13 22:32:01 +08:00
7369b5ee63 fix(ida): retain cleanup facts and let one-shot commands exit (#2814)
* fix(ida): let one-shot commands exit after retaining cleanup

When a headless IDA request outlives timeoutMs (for example idb_open on
a large binary still running auto-analysis), REA cannot prove the
worker stopped and correctly retains the upstream connection and
private workspace. The retained stdio child and its pipes stayed
referenced, so a one-shot CLI printed its cleanup_incomplete result and
then never exited, keeping the supervisor, worker and database alive.

Detach the retained connection's child process and pipes from the event
loop when cleanup fails. A long-lived MCP server can still retry
through the retained connection; a one-shot CLI exits with status 1,
and the supervisor observes end of input.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ida): report an unverified upstream worker after failed cleanup

Upstream ida-pro-mcp spawns headless workers in their own session and
deliberately leaves them running when its supervisor exits, so neither
a retained connection nor REA exiting proves that a timed-out worker
stopped. When cleanup fails before the owned worker's release is
confirmed, the cleanup diagnostics now name its private session and
state that it may still be running until it finishes and reaches its
idle timeout. Failures after a confirmed release, or before any open
was attempted, do not report a worker.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ida): name the inventory sessions that block worker release

When idb_close confirmed the requested worker gone but the follow-up
inventory still found a different peer on the private input, the
upstream_worker diagnostic named the released session and could
misdirect manual cleanup. Record the session ids of the inventory
entries that actually blocked release and report those; fall back to
the requested private session only when no inventory evidence exists
(an incomplete open or an unanswered request). The field becomes
session_ids, since more than one entry can block release.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ida): keep blocker evidence and backend in cleanup diagnostics

The release diagnostic reset its observed blockers on every close, so a
retry whose inventory was unavailable fell back to the already-released
session; and it kept only session ids, describing a blocking GUI
session with detached-worker guidance.

Blocker evidence is now replaced only by a successful inventory, and
the diagnostic becomes upstream_sessions with each session's id and
backend, with guidance that distinguishes workers from GUI sessions.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ida): stop naming a worker after its close was confirmed

When idb_close confirmed the requested worker's release but the
following inventory failed, no blocker evidence existed yet and the
diagnostic fell back to the confirmed-absent worker. After a confirmed
close the diagnostic now reports an empty session list, meaning any
remaining same-input sessions are unknown.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* test(ida): group cleanup diagnostic cases in their own suite

The added cases pushed the reaped-worker describe block past the
150-line limit enforced by lint:built.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ida): keep ownership and pre-close peers in cleanup diagnostics

Blocking sessions dropped the parsed ownership fact, so an external
unowned worker looked the same as REA's own; and recovery inventory
recorded same-input peers only when the requested worker was missing,
so a peer seen beside it was lost if the following close failed.

Each reported session now carries owned (null when no inventory has
reported it), and recovery records every same-input session until a
later successful inventory replaces that evidence.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ida): drop a confirmed worker from retained cleanup blockers

Recovery inventory now records the requested worker beside any peers,
so once idb_close confirmed its release a failing follow-up inventory
still reported it as unreleased. Remove the confirmed session from the
retained blockers at close confirmation and keep the remaining peers.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* test(ida): retry cleanup through a detached stdio connection

The retry coverage used a recording connection whose detach() only
counts calls, so it could not show that detaching keeps a retained
connection usable. Run a real stdio supervisor in a long-lived host,
fail the first post-close inventory, and require the retry through the
same detached connection to confirm release and remove the workspace.
The test fails if detach() destroys the pipes instead of unref-ing them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ida): close the stdio supervisor in failed retry tests

Merge main and give its new IdaNativeProtocol connection double the
required detach() method. The real-stdio retry test now closes its
connection in an unconditional teardown, so a failing assertion cannot
leave the supervisor waiting on stdin.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* test(ida): share the cleanup diagnostic expectation in session tests

Repeated upstream_sessions assertions and the unrelated live peer
literal pushed repository duplication over the jscpd threshold. Build
the expected diagnostic with one helper and reuse one peer constant.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* test(ida): distinguish observed ownership from unreported input bindings

* fix(ida): keep requested-ID conflicts in recovery cleanup

Recovery inventory kept only same-input entries, unlike the startup and
post-close filters. After an explicitly rejected open, an entry under
the requested session ID on another input was dropped, so cleanup could
close the connection, remove the private workspace and report success
while that session stayed registered. Match the requested ID as well so
the entry is retained as a blocker and cleanup stays incomplete.

Also split the cleanup diagnostics suite under the lint:built function
length limit, and make two startup-inventory fixtures pass a defined
session id so the test file typechecks.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ida): preserve retained session inventory facts

---------

Co-authored-by: Xingchuan Ma <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-13 22:27:26 +08:00