Merge remote-tracking branch 'origin/main' into fix/managed-comparison-undecoded-signatures

# Conflicts:
#	docs/product-catalog.json
#	docs/verification/managed-conformance-manifest.json
#	skills/reverse-engineer-anything/SKILL.md
#	src/generatedMcpToolCatalog.ts
This commit is contained in:
Kaoru0822 2026-10-07 08:36:16 +00:00
commit 767c6c9a95
214 changed files with 4517 additions and 835 deletions

View File

@ -244,15 +244,41 @@ jobs:
if: github.event_name == 'push' || needs.changes.outputs.package == 'true'
strategy:
fail-fast: false
max-parallel: 2
matrix:
os: [ubuntu-latest, macos-14]
include:
- os: ubuntu-latest
platform: linux
architecture: x64
- os: ubuntu-24.04-arm
platform: linux
architecture: arm64
- os: macos-14
platform: darwin
architecture: arm64
- os: macos-15-intel
platform: darwin
architecture: x64
runs-on: ${{ matrix.os }}
timeout-minutes: 20
env:
NODE_OPTIONS: "--max-old-space-size=1024"
UV_THREADPOOL_SIZE: "2"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- name: Verify native runtime identity
env:
EXPECTED_CI_PLATFORM: ${{ matrix.platform }}
EXPECTED_CI_ARCHITECTURE: ${{ matrix.architecture }}
run: >-
node -e "const assert = require('node:assert/strict');
assert.equal(process.platform, process.env.EXPECTED_CI_PLATFORM);
assert.equal(process.arch, process.env.EXPECTED_CI_ARCHITECTURE);
console.log(JSON.stringify({ platform: process.platform, architecture: process.arch, node: process.version }));"
- run: npm ci
- uses: actions/download-artifact@v4
with:
@ -318,16 +344,44 @@ jobs:
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
strategy:
fail-fast: false
max-parallel: 2
matrix:
os: [ubuntu-latest, windows-latest]
include:
- os: ubuntu-latest
platform: linux
architecture: x64
- os: ubuntu-24.04-arm
platform: linux
architecture: arm64
- os: macos-14
platform: darwin
architecture: arm64
- os: macos-15-intel
platform: darwin
architecture: x64
- os: windows-latest
platform: win32
architecture: x64
runs-on: ${{ matrix.os }}
timeout-minutes: 10
env:
NODE_OPTIONS: "--max-old-space-size=1024"
UV_THREADPOOL_SIZE: "2"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- name: Verify native runtime identity
env:
EXPECTED_CI_PLATFORM: ${{ matrix.platform }}
EXPECTED_CI_ARCHITECTURE: ${{ matrix.architecture }}
run: >-
node -e "const assert = require('node:assert/strict');
assert.equal(process.platform, process.env.EXPECTED_CI_PLATFORM);
assert.equal(process.arch, process.env.EXPECTED_CI_ARCHITECTURE);
console.log(JSON.stringify({ platform: process.platform, architecture: process.arch, node: process.version }));"
- run: npm ci
- name: Verify real Node Inspector discovery and observation
run: npm run verify:inspector

View File

@ -6,7 +6,7 @@ on:
- ".github/workflows/real-javascript-recovery.yml"
- "src/javascript/recovery/**"
- "src/domain/javascript*.ts"
- "src/application/JavaScriptRecovery*.ts"
- "src/application/javascript/JavaScriptRecovery*.ts"
- "src/composition/javascriptRecovery.ts"
- "src/contracts/javascriptRecoveryToolContracts.ts"
- "src/cli/javascriptRecoveryCommands.ts"
@ -22,8 +22,7 @@ on:
- "scripts/rea.mjs"
- "src/process/**"
- "src/artifacts/SafeOutputTree.ts"
- "scripts/verify-javascript-recovery.mjs"
- "scripts/lib/javascript-recovery-*.mjs"
- "scripts/verify/javascript/recovery.mjs"
- "scripts/fixtures/javascript-recovery/**"
- "third_party/wakaru"
- "package.json"

View File

@ -0,0 +1,50 @@
name: Real website source-map verification
on:
pull_request:
paths:
- ".github/workflows/real-web-source-map.yml"
- "scripts/verify-browser-source-maps.mjs"
- "scripts/lib/browser-source-map-e2e.mjs"
- "scripts/fixtures/browser-source-map-site.mjs"
- "src/javascript/sourceMaps/**"
- "src/browser/assets/**"
- "src/domain/webSource*.ts"
- "src/domain/webScript*.ts"
- "src/application/WebSourceLocation*.ts"
- "src/application/ValidateSelectedWebScript.ts"
- "src/composition/webSourceLocations.ts"
- "src/server/registerWebSourceLocationTool.ts"
- "src/server/createServer.ts"
- "src/contracts/webScriptToolContracts.ts"
- "src/process/**"
- "src/cli/webSourceLocationCommands.ts"
- "src/cli.ts"
- "src/artifacts/readStableArtifact.ts"
- "package.json"
- "package-lock.json"
workflow_dispatch:
permissions:
contents: read
concurrency:
group: real-web-source-map-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
HUSKY: "0"
jobs:
real-web-source-map:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
- name: Install the pinned compiler into an isolated fixture directory
run: npm install --prefix "$RUNNER_TEMP/rea-web-source-map-compiler" --no-audit --no-fund --package-lock=false esbuild@0.25.10
- run: npm run verify:browser:source-maps
env:
REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome
REA_BROWSER_NO_SANDBOX: "true"
REA_WEB_SOURCE_MAP_COMPILER: ${{ runner.temp }}/rea-web-source-map-compiler/node_modules/esbuild/lib/main.js

View File

@ -411,7 +411,7 @@ See [native investigation](docs/native-investigation.md) for keyed archives, ins
| Browser observation | 9 | page structure, network metadata, scripts, source maps, WebMCP discovery, screenshots, and capture comparisons |
| Electron analysis | 5 | renderer observation, static app mapping, and static/runtime reconciliation |
| JavaScript runtime | 2 | Node/Electron Inspector target discovery, script locations, and execution-context events |
| Application workflows | 12 | captured website script export; Android/Apple inventory projections; cross-layer feature traces, build comparisons, historical source mapping, static return-shape comparison, and reconstruction checks |
| Application workflows | 13 | captured website script export; Android/Apple inventory projections; cross-layer feature traces, build comparisons, historical source mapping, static return-shape comparison, and reconstruction checks |
| Workspace and observation | 21 | sessions, evidence bundles, navigation context, process/artifact/function comparisons, and open-question tracking |
The public interface describes what the agent is trying to learn. Providers decide how to answer. macOS utilities handle common semantic inspection without launching Hopper; Hopper handles deeper native analysis; the process harness records direct behavioral captures.
@ -436,6 +436,11 @@ Static Android APK inspection is verified on Linux with headless JADX; see [Andr
`rea trace-web-module-imports`, preserving query/fragment identity and optional
import-map context. Requires caller-supplied Chromium via
`REA_BROWSER_EXECUTABLE`; see [module relationships](docs/website-module-trace.md).
- **Source locations:** Trace one retained website script point through a selected
local source map with `rea trace-web-source-location`. See
[captured website source locations](docs/web-source-location.md) for byte
identities, embedded original content and coverage limits.
Recover readable modules from selected local bundles with
`recover_javascript_sources` / `rea recover-javascript-sources`, then pass
the returned `analysis_input` to static analysis. This optional Linux x64
@ -810,3 +815,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and contribution ch
<img alt="REA GitHub star history" src="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
</picture>
</a>
## Disclaimer
REA provides tools for lawful reverse-engineering research, analysis, and reconstruction. You are responsible for obtaining any required authorization and complying with applicable laws. The project does not endorse illegal or unauthorized use.

View File

@ -223,7 +223,7 @@ rea setup
| مراقبة المتصفح | 9 | بنية الصفحات وبيانات الشبكة والبرامج النصية وخرائط المصدر واكتشاف WebMCP والصور ومقارنة الالتقاط |
| تحليل Electron | 5 | مراقبة العارضين وخريطة التطبيق الثابتة والمواءمة بين نتائج الثبات والتشغيل |
| وقت تشغيل JavaScript | 2 | اكتشاف أهداف Node/Electron Inspector ومواضع البرامج وأحداث سياقات التنفيذ |
| سير عمل التطبيقات | 12 | تصدير النصوص البرمجية الملتقطة، تتبع الميزات عبر الطبقات ومقارنة الإصدارات ومواءمة المصدر التاريخي ومقارنة أشكال القيم المعادة والتحقق من إعادة الإنشاء |
| سير عمل التطبيقات | 13 | تصدير النصوص البرمجية الملتقطة، تتبع الميزات عبر الطبقات ومقارنة الإصدارات ومواءمة المصدر التاريخي ومقارنة أشكال القيم المعادة والتحقق من إعادة الإنشاء |
| مساحة العمل والملاحظة | 21 | الجلسات وحزم الأدلة وسياق التنقل ومقارنة العمليات والمخرجات والدوال وتسجيل الأسئلة غير المحسومة |
## خطة العمل

View File

@ -212,7 +212,7 @@ REA は手順 1〜5 のバイナリ解析を処理し、手順 6 はエージェ
| ブラウザー観察 | 9 | ページ構成、ネットワークメタデータ、スクリプト、ソースマップ、WebMCP 検出、スクリーンショット、キャプチャ比較 |
| Electron 解析 | 5 | レンダラー観察、静的アプリマッピング、静的/実行時結果の対応付け |
| JavaScript 実行時 | 2 | Node/Electron Inspector 対象の検出、スクリプト位置、実行コンテキストイベント |
| アプリワークフロー | 12 | 取得した Web スクリプトのエクスポート、層をまたぐ機能トレース、ビルド比較、履歴ソース対応、静的戻り値形状の比較、再実装検証 |
| アプリワークフロー | 13 | 取得した Web スクリプトのエクスポート、層をまたぐ機能トレース、ビルド比較、履歴ソース対応、静的戻り値形状の比較、再実装検証 |
| ワークスペースと観察 | 21 | セッション、証跡バンドル、ナビゲーション文脈、プロセス・成果物・関数比較、未解決事項の記録 |
## ロードマップ

View File

@ -213,7 +213,7 @@ REA는 1–5단계의 바이너리 분석을 처리합니다. 6단계는 에이
| 브라우저 관찰 | 9 | 페이지 구조, 네트워크 메타데이터, 스크립트, 소스 맵, WebMCP 탐색, 스크린샷, 캡처 비교 |
| Electron 분석 | 5 | 렌더러 관찰, 정적 앱 매핑, 정적·런타임 결과 연결 |
| JavaScript 런타임 | 2 | Node/Electron Inspector 대상 탐색, 스크립트 위치, 실행 컨텍스트 이벤트 |
| 앱 워크플로 | 12 | 캡처한 웹 스크립트 내보내기, 계층 간 기능 추적, 빌드 비교, 히스토리 소스 매핑, 정적 반환 구조 비교, 재구현 검증 |
| 앱 워크플로 | 13 | 캡처한 웹 스크립트 내보내기, 계층 간 기능 추적, 빌드 비교, 히스토리 소스 매핑, 정적 반환 구조 비교, 재구현 검증 |
| 작업 공간과 관찰 | 21 | 세션, 근거 번들, 탐색 컨텍스트, 프로세스·아티팩트·함수 비교, 미해결 항목 기록 |
## 로드맵

View File

@ -212,7 +212,7 @@ REA 负责第 1–5 步中的二进制分析。第 6 步由智能体使用其常
| 浏览器观察 | 9 | 页面结构、网络元数据、脚本、来源映射、WebMCP 发现、截图与捕获比较 |
| Electron 分析 | 5 | 渲染进程观察、静态应用映射、静态/运行时结果关联 |
| JavaScript 运行时 | 2 | Node/Electron Inspector 目标发现、脚本位置与执行上下文事件 |
| 应用工作流 | 12 | 捕获的网站脚本导出、跨层功能追踪、构建比较、历史源码映射、静态返回结构比较与重建验证 |
| 应用工作流 | 13 | 捕获的网站脚本导出、跨层功能追踪、构建比较、历史源码映射、静态返回结构比较与重建验证 |
| 工作区与观察 | 21 | 会话、证据包、导航上下文、进程/产物/函数比较与待解决问题跟踪 |
## 路线图

View File

@ -28,6 +28,7 @@ graph TD
IDA_MCP["External ida-pro-mcp<br/>GUI proxy or database supervisor<br/>upstream installation and engine lifecycle"]
AUX["src/artifacts/ + src/native/<br/>disjoint artifact and native capabilities"]
BROWSER["src/browser/<br/>CDP / Playwright capture<br/>captured scripts and native module resolution"]
JS_CODEC["src/javascript/sourceMaps/<br/>pinned upstream map codec<br/>owned heap-limited Node process, complete point evidence"]
INSPECTOR["src/inspector/<br/>passive V8 Inspector discovery and capture<br/>script and target locations"]
DOTNET["src/dotnet/<br/>Managed static metadata provider<br/>PE/CLI metadata inventory, members, IL"]
FIRMWARE["src/firmware/<br/>Binwalk / Unblob adapters<br/>owned processes, report normalization, private extraction"]
@ -95,6 +96,9 @@ graph TD
SERVER --> CONTRACTS
SERVER --> APP
APP --> BROWSER
APP -->|source-map codec port| JS_CODEC
JS_CODEC --> PROCESS
JS_CODEC --> DOMAIN
APP -->|runtime observation port| INSPECTOR
INSPECTOR -->|shared CDP and file-location helpers| BROWSER
INSPECTOR --> DOMAIN

View File

@ -225,6 +225,49 @@ explicit downloader and fixed manifest belong to `scripts/fixtures/android/`.
JADX CLI/MCP parity requires the fixed APK and existing audited JAR; synthetic
protocol/cancellation success does not establish that engine or an unverified host.
## Deep-provider source declarations
Hopper, Ghidra and IDA declare their implemented analyst operations in their
own `*ProviderCapabilities.ts` modules. Hopper's inventory is typed against the
existing direct-operation contracts; Ghidra reuses its inventory/function adapter
operations; IDA retains its read-only operation family. Frozen operation arrays
feed the existing capability builders without importing generated catalog data.
The catalog generator reads these source declarations and joins operation names
to canonical `TOOL_CONTRACTS`. A missing contract identifies the declaring provider
and operation. Public schemas and descriptions remain owned by contracts; the
declarations describe implementation coverage. Provider adapters must not consume
the generated MCP catalog that is derived from them. The resolved module guard
checks this edge while admitting canonical source contracts, generated package
metadata and the existing application snapshot-cache consumer.
Exact provider effects and lifecycle differences remain in their adapters:
Hopper's GUI and mutation effects, Ghidra's experimental Windows authority and
mutation restrictions, and IDA's attached/headless effects and live observations.
This source increment introduces no common provider lifecycle or new interface.
## JavaScript application ownership
`src/application/javascript/` owns JavaScript/Electron artifact analysis and
graph projection, feature/version/export/source comparisons, runtime Evidence
and reconciliation, observation ports, and source recovery workflows. Pure
analysis and public schemas keep their existing domain/contract ownership;
shared artifact inventory, investigation records and execution types remain
shared. CLI, MCP and production factories import the owning workflow directly.
`scripts/verify/javascript/` groups application-workflow, runtime-reconciliation,
large-digest and real-recovery entrypoints. Their existing npm commands retain
their invocation semantics. Recovery fixture compilation lives beside its
unchanged sources under `scripts/fixtures/javascript-recovery/`. Its default
REA entrypoint still resolves to `scripts/rea.mjs`. Managed conformance imports
the relocated compiled workflow; owning CI source filters follow the new paths.
This application move preserves the current directory/ASAR reader boundary,
including root/nested byte checks, UTF-8 diagnostics, cancellation and owned
close. Reader selection requires a separately traced increment. Runtime ports
retain their distinct Inspector, passive Electron and active Electron effects;
shipped Electron hooks remain at their existing provider boundary.
## Binary application ownership
`src/application/binary/` owns the active session, deep-provider registry and

View File

@ -10,7 +10,7 @@
"skill_version": "26"
},
"tools": {
"total": 130,
"total": 131,
"families": [
{
"id": "direct",
@ -179,7 +179,7 @@
{
"id": "application",
"surface": "application-workflow",
"count": 12,
"count": 13,
"tools": [
"build_reconstruction_obligation_ledger",
"compare_application_versions",
@ -192,7 +192,8 @@
"recover_javascript_sources",
"trace_application_feature",
"trace_javascript_semantics",
"trace_web_module_imports"
"trace_web_module_imports",
"trace_web_source_location"
]
},
{
@ -471,7 +472,11 @@
"id": "rea-web-script-export",
"name": "REA captured script export",
"version": "1",
"capabilities": ["export_web_scripts", "trace_web_module_imports"]
"capabilities": [
"export_web_scripts",
"trace_web_module_imports",
"trace_web_source_location"
]
},
{
"id": "unblob",
@ -561,7 +566,7 @@
}
],
"cli": {
"primary_count": 85,
"primary_count": 86,
"commands": [
"address-to-file-offset",
"analyze",
@ -644,6 +649,7 @@
"trace-native-ui-action",
"trace-native-values",
"trace-web-module-imports",
"trace-web-source-location",
"uninstall",
"update",
"verify-managed-native-boundaries",
@ -658,15 +664,15 @@
},
"runtime_catalog": {
"counts": {
"cli_commands": 85,
"mcp_tools": 130,
"cli_commands": 86,
"mcp_tools": 131,
"mcp_prompts": 6
},
"digests": {
"tools_sha256": "4d67b3d567f690604e29dae3c76d4bdfc7d9a332745302dd27af328642118c66",
"tools_sha256": "f31ac36f25f54a9a5fbc157855849fac5361c67373d8b4bb070cf8171bf833c1",
"prompts_sha256": "ef2de8814390b340623c32001610aa2709d90bed51537b6e562ab3abf144ab4d",
"combined_sha256": "ca2f454e044d0095736974fa078383989ab848e420fcebb6127d2c6869c47f1c",
"providers_sha256": "67251a90abf28e1cd9020cf68f579bf2460922d90dc113798a391039279db009"
"combined_sha256": "f07ae6f3910102f58197c86e34e1f06b3cc1f3bf341faa140b4fa2ff65182764",
"providers_sha256": "a7d885531ee25d42c51385444faec544d34cd7eba6250a7dc75c4faedd4454a3"
}
}
}

View File

@ -179,7 +179,7 @@ requires unresolved table bounds or case mappings to remain visible as
residual unknowns.
`npm run verify:inspector` requires the supported Node.js runtime and installed
REA dependencies. CI runs it on Linux and Windows. It starts owned loopback
REA dependencies. CI runs it on Linux and macOS x64/arm64 and Windows x64. It starts owned loopback
Node Inspector fixtures and verifies discovery and passive observation through
the CLI and stdio MCP, including special filenames, unresolved discovery
locations, and independently resolved loaded scripts. Double-quote filenames
@ -312,6 +312,30 @@ Keep the provider-specific acceptance path independent from optional
cross-compilers. Cross-format failures belong to the cross-format lane and must
not make native host acceptance unavailable.
## Native platform baseline in CI
CI exercises the pinned Node.js runtime on native hosted runners:
| Host | Runner | Baseline checks |
| --------------------- | ------------------ | ---------------------------------------------------------------------------------------- |
| Linux x64 | `ubuntu-latest` | Installed package and real Node Inspector CLI/MCP |
| Linux arm64 (aarch64) | `ubuntu-24.04-arm` | Installed package and real Node Inspector CLI/MCP |
| macOS arm64 | `macos-14` | Installed package and real Node Inspector CLI/MCP |
| macOS x64 | `macos-15-intel` | Installed package and real Node Inspector CLI/MCP |
| Windows x64 | `windows-latest` | Curated capabilities, native controls, installed package and real Node Inspector CLI/MCP |
Package and Inspector matrices assert the actual Node platform/architecture
before verification and record those values with the Node version. Each matrix
runs at most two jobs concurrently with explicit timeouts and Node heap/thread
limits. Package checks cover installation, CLI/MCP discovery, target-free
analysis, configuration backups/recovery, Evidence and owned lifecycle; Inspector
checks execute source-owned loopback targets and special filename cases.
These native baseline checks complement the Linux source-test shards and the
separate Apple-artifact and real-provider lanes. Actual Hopper, Ghidra, IDA,
browser and managed-tool claims require their corresponding verification lanes.
Runner labels follow the [GitHub hosted-runner reference](https://docs.github.com/en/actions/reference/runners/github-hosted-runners).
## Developer commands
Use source feedback while editing, explicit boundary checks for the changed
@ -462,3 +486,25 @@ and compares a finite set of known fixture results. It does not establish
arbitrary recovered-application equivalence. CI installs these prerequisites only
in `.github/workflows/real-javascript-recovery.yml`; the existing `real-browser`
lane uses real Chrome for browser capture and website workflows.
### Captured website source-map lane
`npm run verify:browser:source-maps` checks actual Chromium capture/export and
source-map point tracing through CLI and stdio MCP. It requires absolute
`REA_BROWSER_EXECUTABLE` and `REA_WEB_SOURCE_MAP_COMPILER` pointing to esbuild
0.25.10's `lib/main.js` in a caller-owned isolated installation. Preflight reports
missing prerequisites for this lane. The compiler is used only to generate the
source-owned fixture. No Hopper, Ghidra or application dependency installation
is required.
```bash
REA_BROWSER_EXECUTABLE=/absolute/path/to/chromium \
REA_WEB_SOURCE_MAP_COMPILER=/absolute/path/to/fixture-tools/node_modules/esbuild/lib/main.js \
npm run verify:browser:source-maps
```
`scripts/verify-browser-source-maps.mjs /absolute/path/to/installed/rea.mjs`
checks an installed package after building the verifier dependencies. The separate
conditional `real-web-source-map` CI job supplies Chrome and an isolated pinned
fixture compiler; static/unit checks do not acquire a browser. See
[the source location guide](web-source-location.md) for the verified decoder profile.

View File

@ -1,5 +1,5 @@
{
"manifest_id": "ecm_4e3e927be6545a5328c9e1c523da2504d22f1fae7b3d71ddc6c20e0c6faf34c3",
"manifest_id": "ecm_5705edecb5c3c4e48c75eba9c8a83a8dfaee8b8aec9f2f3eb9a7196d619a1e15",
"verifier": {
"id": "rea-managed-conformance",
"version": "1"
@ -13,7 +13,7 @@
"skill_digests": [
{
"skill_id": "reverse-engineer-anything",
"sha256": "7f689acab3357db8f73aeaf4030e58a1b0c488dfe5a5c3238ce3bb5bcb119bd6"
"sha256": "f37629a65c061591aedf33ba52c38838dd0ccad3e7819a5e36ec640888133030"
}
],
"claims": [

View File

@ -0,0 +1,97 @@
# Captured website source locations
`trace_web_source_location` maps one selected position in a script retained by
`export_web_scripts` through one explicitly paired local source map. The shared
CLI/MCP workflow verifies actual manifest, script and map byte identities and
returns the original position and embedded source inline. It acquires no browser,
fetches no URL and executes no application code.
```bash
rea trace-web-source-location \
/analysis/scripts/manifest.json 0 \
/analysis/app.js.map 'https://example.test/maps/app.js.map?v=7#context' \
1 25 --json
```
The six positional arguments select the manifest, zero-based script index,
absolute map path, absolute map URL context, one-based generated line and
zero-based UTF-16 column. The MCP arguments are:
```json
{
"manifest_path": "/analysis/scripts/manifest.json",
"script_index": 0,
"source_map": {
"path": "/analysis/app.js.map",
"url": "https://example.test/maps/app.js.map?v=7#context"
},
"generated_position": { "line": 1, "column": 25 }
}
```
The URL supplies the context for resolving `sources` and `sourceRoot`; it is not
an instruction to fetch. Absolute virtual or file contexts can be selected as
well. The map/script association is caller-selected: a declaration or local map
does not prove deployment authenticity or execution. Use
[import tracing](website-module-trace.md) to inspect outgoing native module edges.
## Meaning of the evidence
Lookup follows the greatest generated position less than or equal to the
selected point, across lines, and returns **every** segment at that position.
It includes generated-only mappings. This follows
[ECMA-426 GetOriginalPositions](https://tc39.es/ecma426/#sec-getoriginalpositions),
with one-based lines in REA's public contract. A point result does not establish
coverage of a source range, execution or UI causality.
Mapped entries preserve the raw source name/root, section path, section-local
source index and flattened index. Duplicate URLs remain distinct, including
entries with different embedded contents. Missing source names retain a null
resolved URL. Original coordinates outside embedded text retain the reported
coordinates and a null offset.
Embedded content hashes identify the UTF-8 encoding of the decoded
`sourcesContent` string, including its line endings. They do not identify an
independently captured original file. Raw map text is retained in Evidence's
`raw_result`, including unknown extensions; these extensions are not interpreted.
Capture context and source Evidence links accompany independently verified
selected file identities.
## Adapter and resource boundaries
The adapter uses the locked upstream
[`@jridgewell/trace-mapping` 0.3.31](https://github.com/jridgewell/trace-mapping)
without modifying its code. It validates map/VLQ structure before allocation,
normalizes nested indexed offsets before upstream flattening, checks section
boundaries and indexes, and retains raw declaration identity. It supports regular
maps and inline indexed sections. External section URLs return an actionable
unsupported-profile error. This is a defined decoder profile, not a claim to
implement every current source-map extension.
One owned Node subprocess decodes the map. Its private request directory is
removed before success is returned. Only this child's inherited `NODE_OPTIONS`
is removed; explicit V8 flags set a 192 MiB old-generation and 8 MiB semi-space
budget, one V8 worker and a 20-second deadline. Reported actual V8 heap limits
are checked. These are heap limits, not an aggregate process RSS limit. Cleanup
may extend the deadline and an unconfirmed cleanup overrides success with
`cleanup_incomplete` and the owning operation/resources.
Complete evidence is bounded by a 4 MiB map, 32 MiB codec reply, 262144 decoded
rows/segments and 64 nested section levels. Exceeding a budget returns an explicit
failure, without partial results. The existing 32 MiB manifest and 16 MiB selected
script boundaries also apply. No global toolchain or browser configuration changes
are made.
## Verification
Focused tests cover duplicate mappings, indexed offsets/overlap/local indexes,
32-bit VLQ overflow, nullable content, UTF-16/CRLF positions, immutable artifact
identity, cancellation, late output closure, cleanup failures, SDK schemas and
public CLI behavior. The actual codec process is exercised on the test host.
The optional `verify:browser:source-maps` lane compiles a source-owned TypeScript
fixture with isolated esbuild 0.25.10, serves it to real Chromium, captures and
exports the actual response, then checks the original compiler point and exact
retained content through CLI and stdio MCP. It can target an installed package.
Only this lane requires Chromium and the fixture compiler. Linux x64 is the real
workflow covered by the dedicated CI job; other host workflows remain unverified.

View File

@ -136,9 +136,9 @@
"verify:browser:network": "npm run build:cached && node scripts/verify-browser-network.mjs",
"verify:electron": "npm run build:cached && node scripts/verify-real-electron.mjs",
"verify:inspector": "npm run build:cached && node scripts/verify/inspector/runtime-observation.mjs",
"verify:javascript-runtime": "npm run build:cached && node scripts/verify-local-javascript-runtime.mjs",
"verify:javascript:digests": "npm run build:cached && node scripts/verify-large-javascript-digests.mjs",
"verify:application-workflows": "npm run build:cached && node scripts/verify-local-application-workflows.mjs",
"verify:javascript-runtime": "npm run build:cached && node scripts/verify/javascript/runtime-observation.mjs",
"verify:javascript:digests": "npm run build:cached && node scripts/verify/javascript/digests.mjs",
"verify:application-workflows": "npm run build:cached && node scripts/verify/javascript/application-workflows.mjs",
"verify:managed": "npm run build:cached && node scripts/verify-managed-conformance.mjs",
"verify:firmware": "npm run build:cached && node scripts/verify/firmware/analysis.mjs",
"fixtures:firmware": "node scripts/fixtures/firmware/generate.mjs",
@ -179,8 +179,9 @@
"verify:browser:scripts": "npm run build:cached && node scripts/verify-browser-scripts.mjs",
"verify:browser:modules": "npm run build:cached && node scripts/verify-browser-modules.mjs",
"verify:test-discovery": "node scripts/verify-test-discovery.mjs",
"verify:javascript:recovery": "node scripts/verify-javascript-recovery.mjs",
"verify:module-boundaries": "node scripts/verify-module-boundaries.mjs"
"verify:javascript:recovery": "node scripts/verify/javascript/recovery.mjs",
"verify:module-boundaries": "node scripts/verify-module-boundaries.mjs",
"verify:browser:source-maps": "npm run build:cached && node scripts/verify-browser-source-maps.mjs"
},
"lint-staged": {
"*.{cjs,cts,js,jsx,mjs,mts,ts,tsx}": [

View File

@ -0,0 +1,77 @@
import { createServer } from "node:http";
import { pathToFileURL } from "node:url";
import { access } from "node:fs/promises";
import { isAbsolute } from "node:path";
/** Generate a real compiler map and serve only source-owned fixture code. */
export async function startBrowserSourceMapSite() {
const command = process.env.REA_WEB_SOURCE_MAP_COMPILER;
if (!command || !isAbsolute(command))
throw new Error(
"verify:browser:source-maps requires absolute REA_WEB_SOURCE_MAP_COMPILER pointing to isolated esbuild 0.25.10 lib/main.js",
);
await access(command);
const compiler = await import(pathToFileURL(command).href);
if (compiler.version !== "0.25.10")
throw new Error(`Expected esbuild 0.25.10; observed ${compiler.version}`);
const original =
'// 🎋 UTF-16 and CRLF fixture\r\nfunction boot(): void {\r\n const marker: string = "source-map proof";\r\n document.body.dataset.ready = marker;\r\n}\r\nboot();\r\n';
const compiled = await compiler
.transform(original, {
loader: "ts",
sourcefile: "../src/fixture.ts?v=7#original",
sourcemap: "external",
minify: true,
format: "iife",
target: "es2022",
})
.finally(() => compiler.stop());
const token = '"source-map proof"';
const generatedOffset = compiled.code.indexOf(token);
const originalOffset = original.indexOf(token);
if (generatedOffset < 0 || originalOffset < 0)
throw new Error("Compiler fixture marker missing");
const position = textPosition(compiled.code, generatedOffset);
const originalPosition = textPosition(original, originalOffset);
let mapRequests = 0;
const server = createServer((request, response) => {
if (request.url === "/")
return response
.writeHead(200, { "Content-Type": "text/html" })
.end('<body><script src="/app.js?build=7"></script></body>');
if (request.url === "/app.js?build=7")
return response
.writeHead(200, { "Content-Type": "text/javascript" })
.end(compiled.code);
if (request.url?.startsWith("/maps/app.js.map")) {
mapRequests += 1;
return response
.writeHead(200, { "Content-Type": "application/json" })
.end(compiled.map);
}
response.writeHead(404).end("Unselected");
});
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
const address = server.address();
if (!address || typeof address === "string")
throw new Error("Source map fixture has no TCP address");
return {
origin: `http://127.0.0.1:${address.port}`,
original,
generated: compiled.code,
map: compiled.map,
position,
originalPosition,
originalOffset,
mapRequests: () => mapRequests,
compiler: { id: "esbuild", version: compiler.version },
close: () =>
new Promise((resolve, reject) =>
server.close((error) => (error ? reject(error) : resolve())),
),
};
}
const textPosition = (text, offset) => {
const preceding = text.slice(0, offset).split(/\r\n?|\n|\u2028|\u2029/u);
return { line: preceding.length, column: preceding.at(-1).length };
};

View File

@ -17,9 +17,7 @@ export async function buildRecoveryFixtures(root, prefix) {
throw new Error(
"Fixture compilers must be esbuild 0.25.10 and webpack 5.101.3",
);
const source = fileURLToPath(
new URL("../fixtures/javascript-recovery/entry.mjs", import.meta.url),
);
const source = fileURLToPath(new URL("./entry.mjs", import.meta.url));
const webpackOutput = join(root, "webpack");
await mkdir(webpackOutput);
await new Promise((resolve, reject) => {
@ -50,9 +48,7 @@ export async function buildRecoveryFixtures(root, prefix) {
});
// One self-contained source fixture avoids unresolved imports in the oracle.
const helperSource = await readFile(
fileURLToPath(
new URL("../fixtures/javascript-recovery/helpers.mjs", import.meta.url),
),
fileURLToPath(new URL("./helpers.mjs", import.meta.url)),
"utf8",
);
const plain = await esbuild.transform(

View File

@ -0,0 +1,193 @@
import assert from "node:assert/strict";
import { execFile } from "node:child_process";
import { createHash } from "node:crypto";
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { promisify } from "node:util";
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
import { parseEvidence } from "../../dist/domain/evidence.js";
import { webSourceLocationResultSchema } from "../../dist/domain/webSourceLocation.js";
import { startBrowserSourceMapSite } from "../fixtures/browser-source-map-site.mjs";
import { mcpTextValue } from "./mcp-verifier-results.mjs";
/** Verify real Chrome capture → export → original compiler point through packaged CLI/MCP. */
export async function verifyBrowserSourceMap(
executable,
entrypoint = fileURLToPath(new URL("../rea.mjs", import.meta.url)),
) {
const site = await startBrowserSourceMapSite();
const root = await mkdtemp(join(tmpdir(), "rea-browser-source-map-"));
const env = {
...process.env,
REA_LOG_LEVEL: "silent",
HOPPER_LAUNCHER_PATH: "/rea-unconfigured-provider/hopper",
};
const cli = async (...args) => {
const { stdout } = await promisify(execFile)(
process.execPath,
[entrypoint, ...args, "--json"],
{ env, timeout: 45000, maxBuffer: 16 * 1024 * 1024 },
);
return parseEvidence(JSON.parse(stdout));
};
const transport = new StdioClientTransport({
command: process.execPath,
args: [entrypoint, "mcp"],
env,
stderr: "pipe",
});
const client = new Client({ name: "source-map-real-e2e", version: "1" });
try {
const capture = await cli(
"capture-browser-scenario",
JSON.stringify({
browser: { mode: "launch", executable_path: executable },
start_url: { url: site.origin },
actions: [
{
step_id: "ready",
action: "wait_for",
locator: {
kind: "css",
selector: '[data-ready="source-map proof"]',
},
state: "visible",
timeout_ms: 10000,
},
],
capture: { network: { response_body: true } },
}),
);
const capturePath = join(root, "capture.json");
await writeFile(capturePath, JSON.stringify(capture));
const exported = await cli(
"export-web-scripts",
capturePath,
join(root, "export"),
);
const manifest = exported.normalized_result;
const manifestBytes = await readFile(manifest.manifest.path);
const identity = {
sha256: sha(manifestBytes),
bytes: manifestBytes.length,
};
const scriptIndex = manifest.scripts.findIndex(
(script) => script.url === `${site.origin}/app.js?build=7`,
);
assert.ok(
scriptIndex >= 0,
"Actual browser capture omitted compiled source",
);
const mapPath = join(root, "app.js.map");
await writeFile(mapPath, site.map);
const before = site.mapRequests();
await client.connect(transport);
let expected;
for (const context of [
site.origin,
site.origin.replace("://", "://selected-user:selected-value@"),
]) {
const input = {
manifest_path: manifest.manifest.path,
script_index: scriptIndex,
source_map: {
path: mapPath,
url: `${context}/maps/app.js.map?v=7#context`,
},
generated_position: site.position,
};
expected = await assertPublicPair(cli, client, {
site,
input,
capture,
identity,
});
}
assert.equal(
site.mapRequests(),
before,
"Point tracing fetched the selected map URL",
);
return {
compiler: site.compiler,
generated_sha256: sha(site.generated),
source_map_sha256: sha(site.map),
original_sha256: sha(site.original),
public_cli: true,
public_stdio_mcp: true,
actual_chrome_capture: true,
source_map_refetch: false,
original_point: site.originalPosition,
codec: expected.engine,
runtime: expected.runtime,
selected_inert_userinfo_context_preserved: true,
public_point_cases: 4,
};
} finally {
await client.close();
await transport.close();
await site.close();
await rm(root, { recursive: true, force: true });
}
}
function assertPoint(evidence, { site, input, capture, identity }) {
const result = webSourceLocationResultSchema.parse(
evidence.normalized_result,
);
assert.equal(result.manifest.sha256, identity.sha256);
assert.equal(result.manifest.bytes, identity.bytes);
assert.equal(result.source.bytes, Buffer.byteLength(site.generated));
assert.equal(result.source.sha256, sha(site.generated));
assert.equal(result.source_map.sha256, sha(site.map));
assert.equal(result.source_map.url, input.source_map.url);
assert.equal(result.manifest.source_evidence_id, capture.evidence_id);
assert.equal(result.execution, "unknown");
assert.equal(result.source_authenticity, "unknown");
assert.equal(result.matches.length, 1);
const match = result.matches[0];
assert.equal(match.state, "mapped");
assert.deepEqual(match.original_position, {
...site.originalPosition,
offset: site.originalOffset,
content_position: "verified-in-embedded-text",
});
assert.equal(
match.resolved_url,
new URL("../src/fixture.ts?v=7#original", input.source_map.url).href,
);
assert.equal(match.content.state, "embedded");
assert.equal(match.content.text, site.original);
assert.equal(match.content.utf8_sha256, sha(site.original));
assert.ok(result.runtime.v8_heap_limit_bytes <= 256 * 1024 * 1024);
assert.deepEqual(evidence.raw_result, { source_map_text: site.map });
return result;
}
const sha = (text) => createHash("sha256").update(text).digest("hex");
async function assertPublicPair(cli, client, oracle) {
const { input } = oracle;
const evidence = await cli(
"trace-web-source-location",
input.manifest_path,
String(input.script_index),
input.source_map.path,
input.source_map.url,
String(input.generated_position.line),
String(input.generated_position.column),
);
const expected = assertPoint(evidence, oracle);
const response = await client.callTool({
name: "trace_web_source_location",
arguments: input,
});
assert.notEqual(response.isError, true, mcpTextValue(response));
const mcpEvidence = parseEvidence(
JSON.parse(mcpTextValue(response)).evidence,
);
assert.deepEqual(assertPoint(mcpEvidence, oracle), expected);
assert.equal(evidence.parameters.source_map.url, input.source_map.url);
return expected;
}

View File

@ -96,6 +96,21 @@ export const toolFamilyCatalog = (sources) => {
/** Build provider identities with their sorted capability names. */
export const providerCatalog = (sources) => {
const contractsByName = new Map(
sources.toolContracts.TOOL_CONTRACTS.map((contract) => [
contract.name,
contract,
]),
);
const declaredContracts = (providerId, operations) =>
operations.map((operation) => {
const contract = contractsByName.get(operation);
if (contract === undefined)
throw new TypeError(
`Provider ${providerId} declares an unknown analyst operation: ${operation}`,
);
return contract;
});
const {
applicationContracts,
reconciliationContracts,
@ -105,15 +120,21 @@ export const providerCatalog = (sources) => {
return [
{
identity: sources.hopperProvider.HOPPER_PROVIDER_IDENTITY,
contracts: sources.hopperProvider.HOPPER_PROVIDER_TOOL_CONTRACTS,
contracts: declaredContracts(
"hopper",
sources.hopperProvider.HOPPER_OPERATIONS,
),
},
{
identity: sources.ghidraProvider.GHIDRA_PROVIDER_IDENTITY,
contracts: sources.ghidraProvider.GHIDRA_PROVIDER_TOOL_CONTRACTS,
contracts: declaredContracts(
"ghidra",
sources.ghidraProvider.GHIDRA_OPERATIONS,
),
},
{
identity: sources.idaProvider.IDA_PROVIDER_IDENTITY,
contracts: sources.idaProvider.IDA_PROVIDER_TOOL_CONTRACTS,
contracts: declaredContracts("ida", sources.idaProvider.IDA_OPERATIONS),
},
{
identity: sources.nativeProvider.NATIVE_MACOS_PROVIDER_IDENTITY,

View File

@ -59,8 +59,8 @@ const SOURCE_PATHS = {
"dist/contracts/javascriptRecoveryToolContracts.js",
javascriptRecoveryProvider: "dist/javascript/recovery/WakaruRelease.js",
supportedClients: "dist/application/SupportedClients.js",
hopperProvider: "dist/hopper/HopperProvider.js",
ghidraProvider: "dist/ghidra/GhidraProvider.js",
hopperProvider: "dist/hopper/HopperProviderCapabilities.js",
ghidraProvider: "dist/ghidra/GhidraProviderCapabilities.js",
idaProvider: "dist/ida/IdaProviderCapabilities.js",
nativeProvider: "dist/native/NativeMacOSProviderMetadata.js",
artifactProviders: "dist/application/InvestigationProviders.js",

View File

@ -5,7 +5,7 @@ import { parseBinaryTarget } from "../../dist/application/BinaryTargetResolver.j
import { inspectManagedArtifactBytes } from "../../dist/dotnet/ManagedArtifactInspector.js";
import { inspectManagedMembersBytes } from "../../dist/dotnet/ManagedMemberInspector.js";
import { projectManagedApplicationGraphEvidence } from "../../dist/application/ManagedApplicationGraphService.js";
import { traceApplicationFeatureEvidence } from "../../dist/application/JavaScriptApplicationWorkflowService.js";
import { traceApplicationFeatureEvidence } from "../../dist/application/javascript/JavaScriptApplicationWorkflowService.js";
import { createEvidence } from "../../dist/domain/evidence.js";
import { MANAGED_STATIC_PROVIDER } from "../../dist/application/InvestigationProviders.js";
import {

View File

@ -7,7 +7,8 @@ export interface ModuleBoundaryViolation {
readonly boundary:
| "pure-layer"
| "application-composition"
| "provider-construction";
| "provider-construction"
| "provider-generated-catalog";
}
/** Check resolved source ownership, including type imports and reexports. */

View File

@ -13,6 +13,13 @@ const MIGRATED_PROVIDER_ROOTS = new Set([
"inspector",
"javascript",
]);
const PROVIDER_ROOTS = new Set([
...MIGRATED_PROVIDER_ROOTS,
"artifacts",
"browser",
"dotnet",
"native",
]);
const repositoryPath = (root, path) =>
relative(root, path).replaceAll("\\", "/");
@ -53,6 +60,11 @@ const failedBoundary = (file, target) => {
if (!file.startsWith("src/") || !target.startsWith("src/")) return undefined;
const layer = file.split("/")[1];
const targetLayer = target.split("/")[1];
if (
PROVIDER_ROOTS.has(layer) &&
/^src\/generatedMcpToolCatalog\.(?:js|ts)$/u.test(target)
)
return "provider-generated-catalog";
if (PURE_LAYERS.has(layer)) {
if (
(/^src\/[^/]+\//u.test(target) && !PURE_LAYERS.has(targetLayer)) ||

View File

@ -0,0 +1,16 @@
#!/usr/bin/env node
import { access } from "node:fs/promises";
import { isAbsolute } from "node:path";
import { verifyBrowserSourceMap } from "./lib/browser-source-map-e2e.mjs";
import { createVerifierRun, completeVerifierRun } from "./lib/verifier-run.mjs";
const executable = process.env.REA_BROWSER_EXECUTABLE;
if (!executable || !isAbsolute(executable))
throw new Error(
"verify:browser:source-maps requires absolute REA_BROWSER_EXECUTABLE pointing to caller-supplied Chromium",
);
await access(executable);
const run = createVerifierRun();
const proof = await verifyBrowserSourceMap(executable, process.argv[2]);
process.stdout.write(
`${JSON.stringify({ ...proof, verifier_run: await completeVerifierRun(run), verified: true })}\n`,
);

View File

@ -10,7 +10,7 @@ import { compareManagedMemberPaths } from "../dist/application/ManagedMemberComp
import { verifyManagedNativeBoundariesEvidence } from "../dist/application/ManagedNativeVerificationService.js";
import { importManagedReconstructionEvidence } from "../dist/application/ManagedReconstructionService.js";
import { projectManagedApplicationGraphEvidence } from "../dist/application/ManagedApplicationGraphService.js";
import { traceApplicationFeatureEvidence } from "../dist/application/JavaScriptApplicationWorkflowService.js";
import { traceApplicationFeatureEvidence } from "../dist/application/javascript/JavaScriptApplicationWorkflowService.js";
import { MANAGED_STATIC_PROVIDER } from "../dist/application/InvestigationProviders.js";
import { createEvidence } from "../dist/domain/evidence.js";
import {

View File

@ -3,16 +3,19 @@
import { realpath } from "node:fs/promises";
import { parseArgs } from "node:util";
import { analyzeJavaScriptApplication } from "../dist/application/JavaScriptApplicationService.js";
import { analyzeJavaScriptApplication } from "../../../dist/application/javascript/JavaScriptApplicationService.js";
import {
compareApplicationVersionsEvidence,
compareJavaScriptExportShapesEvidence,
traceApplicationFeatureEvidence,
} from "../dist/application/JavaScriptApplicationWorkflowService.js";
import { applicationVersionComparisonResultSchema } from "../dist/domain/javascriptApplicationVersionComparisonSchemas.js";
import { applicationFeatureTraceResultSchema } from "../dist/domain/javascriptFeatureTraceSchemas.js";
import { javaScriptExportShapeComparisonResultSchema } from "../dist/domain/javascriptExportShapeComparisonSchemas.js";
import { completeVerifierRun, createVerifierRun } from "./lib/verifier-run.mjs";
} from "../../../dist/application/javascript/JavaScriptApplicationWorkflowService.js";
import { applicationVersionComparisonResultSchema } from "../../../dist/domain/javascriptApplicationVersionComparisonSchemas.js";
import { applicationFeatureTraceResultSchema } from "../../../dist/domain/javascriptFeatureTraceSchemas.js";
import { javaScriptExportShapeComparisonResultSchema } from "../../../dist/domain/javascriptExportShapeComparisonSchemas.js";
import {
completeVerifierRun,
createVerifierRun,
} from "../../lib/verifier-run.mjs";
const verifierRun = createVerifierRun();

View File

@ -4,8 +4,11 @@ import assert from "node:assert/strict";
import { constants } from "node:buffer";
import { createHash } from "node:crypto";
import { canonicalDigest } from "../dist/domain/comparisonSemantics.js";
import { createEvidence, parseEvidence } from "../dist/domain/evidence.js";
import { canonicalDigest } from "../../../dist/domain/comparisonSemantics.js";
import {
createEvidence,
parseEvidence,
} from "../../../dist/domain/evidence.js";
// This opt-in check crosses the actual engine string limit; keep it outside
// routine source tests. Build first, then run this script with the local Node.

View File

@ -9,10 +9,10 @@ import { fileURLToPath } from "node:url";
import { promisify } from "node:util";
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
import { parseEvidence } from "../dist/domain/evidence.js";
import { javascriptRecoveryResultSchema } from "../dist/domain/javascriptRecovery.js";
import { buildRecoveryFixtures } from "./lib/javascript-recovery-fixtures.mjs";
import { mcpTextValue } from "./lib/mcp-verifier-results.mjs";
import { parseEvidence } from "../../../dist/domain/evidence.js";
import { javascriptRecoveryResultSchema } from "../../../dist/domain/javascriptRecovery.js";
import { buildRecoveryFixtures } from "../../fixtures/javascript-recovery/build.mjs";
import { mcpTextValue } from "../../lib/mcp-verifier-results.mjs";
const OFFICIAL_BINARY_SHA256 =
"e8c7ca052974604197389f6ace7464e4dd24dce64e2730971521bd6606ec9c9e";
@ -21,7 +21,7 @@ if (!process.env.REA_WAKARU_COMMAND)
"Provide REA_WAKARU_COMMAND for the official Wakaru 1.13.0 Linux x64 binary",
);
const entrypoint =
process.argv[2] ?? fileURLToPath(new URL("./rea.mjs", import.meta.url));
process.argv[2] ?? fileURLToPath(new URL("../../rea.mjs", import.meta.url));
const root = await mkdtemp(join(tmpdir(), "rea-real-recovery-"));
const environment = { ...process.env, REA_LOG_LEVEL: "silent" };
const transport = new StdioClientTransport({

View File

@ -3,9 +3,12 @@
import { readFile, realpath } from "node:fs/promises";
import { parseArgs } from "node:util";
import { analyzeJavaScriptApplication } from "../dist/application/JavaScriptApplicationService.js";
import { reconcileJavaScriptRuntimeEvidence } from "../dist/application/JavaScriptRuntimeReconciliationService.js";
import { completeVerifierRun, createVerifierRun } from "./lib/verifier-run.mjs";
import { analyzeJavaScriptApplication } from "../../../dist/application/javascript/JavaScriptApplicationService.js";
import { reconcileJavaScriptRuntimeEvidence } from "../../../dist/application/javascript/JavaScriptRuntimeReconciliationService.js";
import {
completeVerifierRun,
createVerifierRun,
} from "../../lib/verifier-run.mjs";
const verifierRun = createVerifierRun();

View File

@ -3,8 +3,8 @@ name: reverse-engineer-anything
description: Reverse engineer native, managed, Electron/JavaScript, packaged, firmware, and browser targets with REA. Use shipped-artifact or requested runtime evidence to explain features, compare versions, decompile code, or guide a reconstruction. Skip REA for ordinary source-repository architecture analysis.
metadata:
version: "26"
tool_count: 130
catalog_digest: "ca2f454e044d0095736974fa078383989ab848e420fcebb6127d2c6869c47f1c"
tool_count: 131
catalog_digest: "f07ae6f3910102f58197c86e34e1f06b3cc1f3bf341faa140b4fa2ff65182764"
---
# REA

View File

@ -12,9 +12,10 @@ import { execFile } from "node:child_process";
import { extname, isAbsolute, join, resolve } from "node:path";
import { promisify } from "node:util";
import { parse as parsePlist } from "plist";
import { z } from "zod";
import { isPathWithinRoot } from "../domain/localPath.js";
import { parseXmlPropertyList } from "../domain/propertyListKeys.js";
import { BinaryTargetError } from "../domain/configurationErrors.js";
import type { BinaryTarget } from "../domain/binaryTargetTypes.js";
import { err, ok, type Result } from "../domain/result.js";
@ -268,21 +269,15 @@ const resolveAppBundle = async (
/** Decode the top-level executable name with an XML parser, not a pattern. */
const parseXmlPlistExecutable = (plist: string): string => {
const value = parsePlist(plist);
const executable =
typeof value === "object" &&
value !== null &&
!Array.isArray(value) &&
!(value instanceof Date) &&
!(value instanceof Uint8Array) &&
Object.hasOwn(value, "CFBundleExecutable")
? value.CFBundleExecutable
: undefined;
if (typeof executable !== "string")
throw new Error("CFBundleExecutable is missing");
return executable;
// An unrelated `__proto__` entry must not make the bundle unreadable.
const { value } = parseXmlPropertyList(plist);
const executable = executableEntrySchema.safeParse(value);
if (!executable.success) throw new Error("CFBundleExecutable is missing");
return executable.data.CFBundleExecutable;
};
const executableEntrySchema = z.looseObject({ CFBundleExecutable: z.string() });
const readBinaryPlistExecutable = async (plistPath: string): Promise<string> =>
// `-n` strips only the newline plutil appends; it requires macOS 12+.
(

View File

@ -1,7 +1,8 @@
import { createHash } from "node:crypto";
import { parse, parseBinary } from "plist";
import { parseBinary } from "plist";
import { DirectoryArtifactReader } from "../artifacts/DirectoryArtifactReader.js";
import { parseXmlPropertyList } from "../domain/propertyListKeys.js";
import {
decodeNibArchive,
type NibArchiveDocument,
@ -373,6 +374,6 @@ const decodePlist = (bytes: Buffer): JsonValue => {
const parsed =
bytes.subarray(0, 8).toString("ascii") === "bplist00"
? parseBinary(bytes)
: parse(bytes.toString("utf8"));
: parseXmlPropertyList(bytes.toString("utf8")).value;
return jsonValueSchema.parse(parsed);
};

View File

@ -1,8 +1,8 @@
import type { BrowserObservationPort } from "./BrowserObservationPort.js";
import type { BrowserScenarioCapturePort } from "./BrowserScenarioCapturePort.js";
import type { ElectronObservationPort } from "./ElectronObservationPort.js";
import type { ElectronActiveObservationPort } from "./ElectronActiveObservationPort.js";
import type { JavaScriptRuntimeObservationPort } from "./JavaScriptRuntimeObservationPort.js";
import type { ElectronObservationPort } from "./javascript/ElectronObservationPort.js";
import type { ElectronActiveObservationPort } from "./javascript/ElectronActiveObservationPort.js";
import type { JavaScriptRuntimeObservationPort } from "./javascript/JavaScriptRuntimeObservationPort.js";
import { AnalysisCapabilityUnavailableError } from "../domain/analysisErrorCore.js";
/** Existing observation ports loaded independently at MCP startup. */

View File

@ -12,7 +12,7 @@ import type {
ReconstructionObligation,
ReviewedReconstructionObligation,
} from "../domain/reconstructionObligationLedgerSchemas.js";
import { parseApplicationGraphEvidence } from "./JavaScriptApplicationEvidenceGraph.js";
import { parseApplicationGraphEvidence } from "./javascript/JavaScriptApplicationEvidenceGraph.js";
import {
applicationObligationPolicy,
semanticObligationPolicy,

View File

@ -0,0 +1,48 @@
import { createHash } from "node:crypto";
import type { AnalysisError } from "../domain/analysisErrorBase.js";
import { AnalysisOutputError } from "../domain/analysisErrorCore.js";
import { err, ok, type Result } from "../domain/result.js";
import type {
SelectedWebScriptArtifacts,
SelectedWebScriptInput,
} from "../domain/webScriptArtifacts.js";
import type { ExportedWebScript } from "../domain/webScriptExport.js";
/** Bind actual source text to the selected manifest entry before analysis. */
export const validateSelectedWebScript = (
input: SelectedWebScriptInput,
data: SelectedWebScriptArtifacts,
operation: string,
): Result<ExportedWebScript, AnalysisError> => {
const selected = data.manifest.scripts[input.script_index];
if (
selected === undefined ||
selected.content.state !== "exported" ||
selected.content.sha256 !== data.sourceFile.sha256 ||
selected.content.bytes !== data.sourceFile.bytes ||
Buffer.byteLength(data.source) !== data.sourceFile.bytes ||
createHash("sha256").update(data.source, "utf8").digest("hex") !==
data.sourceFile.sha256 ||
data.manifestFile.path !== input.manifest_path
)
return err(
new AnalysisOutputError(
operation,
"Artifact port changed the selected script/source identity.",
),
);
return ok(selected);
};
/** Carry reported capture context alongside independently verified manifest bytes. */
export const capturedWebManifestIdentity = (
data: SelectedWebScriptArtifacts,
) => ({
...data.manifestFile,
reported_output_directory: data.manifest.output_directory,
capture_sha256: data.manifest.capture_sha256,
capture_path: data.manifest.capture_path,
capture_kind: data.manifest.capture_kind,
capture_completeness: data.manifest.capture_completeness,
source_evidence_id: data.manifest.source_evidence_id,
});

View File

@ -6,18 +6,13 @@ import type {
WebModuleResolution,
WebModuleTraceInput,
} from "../domain/webModuleTrace.js";
import type { webScriptExportManifestSchema } from "../domain/webScriptExport.js";
import type { z } from "zod";
import type { SelectedWebScriptArtifacts } from "../domain/webScriptArtifacts.js";
import type { ExecutionOptions } from "./AnalysisProvider.js";
type JsonObject = Record<string, JsonValue>;
/** Verified selected source and capture metadata; provider protocols stay outside. */
export interface WebModuleArtifacts {
readonly manifest: z.output<typeof webScriptExportManifestSchema>;
readonly manifestFile: WebModuleFile;
readonly sourceFile: WebModuleFile;
readonly source: string;
export interface WebModuleArtifacts extends SelectedWebScriptArtifacts {
readonly importMap: {
readonly file: WebModuleFile;
readonly baseUrl: string;

View File

@ -1,5 +1,4 @@
import { isAbsolute } from "node:path";
import { createHash } from "node:crypto";
import { z } from "zod";
import type { AnalysisError } from "../domain/analysisErrorBase.js";
import {
@ -24,7 +23,11 @@ import {
type WebModuleResolution,
type WebModuleTraceResult,
} from "../domain/webModuleTrace.js";
import { webScriptExportManifestSchema } from "../domain/webScriptExport.js";
import { selectedWebScriptArtifactsSchema } from "../domain/webScriptArtifacts.js";
import {
capturedWebManifestIdentity,
validateSelectedWebScript,
} from "./ValidateSelectedWebScript.js";
import type { ExecutionOptions } from "./AnalysisProvider.js";
import type {
WebModuleArtifactPort,
@ -33,11 +36,7 @@ import type {
} from "./WebModulePorts.js";
const OPERATION = "trace_web_module_imports";
const artifactsSchema = z.strictObject({
manifest: webScriptExportManifestSchema,
manifestFile: webModuleFileSchema,
sourceFile: webModuleFileSchema,
source: z.string(),
const artifactsSchema = selectedWebScriptArtifactsSchema.extend({
importMap: z
.strictObject({
file: webModuleFileSchema,
@ -125,23 +124,9 @@ export class WebModuleTraceService {
"Artifact port changed the selected import-map identity/context.",
),
);
const selected = data.manifest.scripts[input.script_index];
if (
selected === undefined ||
selected.content.state !== "exported" ||
selected.content.sha256 !== data.sourceFile.sha256 ||
selected.content.bytes !== data.sourceFile.bytes ||
Buffer.byteLength(data.source) !== data.sourceFile.bytes ||
createHash("sha256").update(data.source, "utf8").digest("hex") !==
data.sourceFile.sha256 ||
data.manifestFile.path !== input.manifest_path
)
return err(
new AnalysisOutputError(
OPERATION,
"Artifact port did not bind the selected source and manifest identities.",
),
);
const bound = validateSelectedWebScript(input, data, OPERATION);
if (!bound.ok) return bound;
const selected = bound.value;
const importerUrl = input.importer_url ?? selected.url;
const importerAdmission = admitContext(importerUrl, ["importer_url"]);
if (!importerAdmission.ok) return importerAdmission;
@ -215,15 +200,7 @@ export class WebModuleTraceService {
});
}
const normalized = webModuleTraceResultSchema.safeParse({
manifest: {
...data.manifestFile,
reported_output_directory: data.manifest.output_directory,
capture_sha256: data.manifest.capture_sha256,
capture_path: data.manifest.capture_path,
capture_kind: data.manifest.capture_kind,
capture_completeness: data.manifest.capture_completeness,
source_evidence_id: data.manifest.source_evidence_id,
},
manifest: capturedWebManifestIdentity(data),
source: {
...data.sourceFile,
script_index: input.script_index,

View File

@ -0,0 +1,15 @@
import type { AnalysisError } from "../domain/analysisErrorBase.js";
import type { Result } from "../domain/result.js";
import type {
SelectedWebScriptArtifacts,
SelectedWebScriptInput,
} from "../domain/webScriptArtifacts.js";
import type { ExecutionOptions } from "./AnalysisProvider.js";
/** Read the caller-selected capture export and verify the selected source identity. */
export interface WebScriptArtifactPort {
load(
input: SelectedWebScriptInput,
options?: ExecutionOptions,
): Promise<Result<SelectedWebScriptArtifacts, AnalysisError>>;
}

View File

@ -0,0 +1,40 @@
import type { AnalysisError } from "../domain/analysisErrorBase.js";
import type { Result } from "../domain/result.js";
import type {
WebSourceLocationInput,
WebSourceMapReport,
} from "../domain/webSourceLocation.js";
import type { SelectedWebScriptArtifacts } from "../domain/webScriptArtifacts.js";
import type { z } from "zod";
import type { webArtifactFileSchema } from "../domain/webScriptArtifacts.js";
import type { ExecutionOptions } from "./AnalysisProvider.js";
/** Actual selected source and local map bytes; no provider URL fetching. */
export interface WebSourceLocationArtifacts extends SelectedWebScriptArtifacts {
readonly sourceMap: {
readonly file: z.output<typeof webArtifactFileSchema>;
readonly url: string;
readonly text: string;
};
}
/** Replaceable artifact acquisition boundary for a caller-selected pairing. */
export interface WebSourceLocationArtifactPort {
load(
input: WebSourceLocationInput,
options?: ExecutionOptions,
): Promise<Result<WebSourceLocationArtifacts, AnalysisError>>;
}
/** Replaceable codec receives map data and one explicit generated point. */
export interface WebSourceMapPort {
trace(
input: {
readonly text: string;
readonly path: string;
readonly url: string;
readonly position: WebSourceLocationInput["generated_position"];
},
options?: ExecutionOptions,
): Promise<Result<WebSourceMapReport, AnalysisError>>;
}

View File

@ -0,0 +1,151 @@
import { expect, it } from "vitest";
import {
webSourceLocationArgs as args,
webSourceLocationFixture,
webSourceMapDecoderFixture as decoder,
} from "../../tests/fixtures/webSourceLocation.js";
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
import { ok } from "../domain/result.js";
import { webSourceLocationResultSchema } from "../domain/webSourceLocation.js";
import { WebSourceLocationService } from "./WebSourceLocationService.js";
import type { WebSourceMapPort } from "./WebSourceLocationPorts.js";
const service = (data = webSourceLocationFixture(), port = decoder) =>
new WebSourceLocationService({ load: () => Promise.resolve(ok(data)) }, port);
it("joins byte identity and historical capture context while keeping selected authenticity/execution unknown", async () => {
const data = webSourceLocationFixture();
data.manifest.source_evidence_id = `ev_${"a".repeat(64)}`;
const response = await service(data).trace(args);
if (!response.ok) throw response.error;
const result = webSourceLocationResultSchema.parse(
response.value.normalized_result,
);
expect(result).toMatchObject({
source: { sha256: data.sourceFile.sha256 },
source_map: {
association: "caller-selected",
sha256: data.sourceMap.file.sha256,
},
matches: [{ state: "mapped", content: { text: "original" } }],
execution: "unknown",
source_authenticity: "unknown",
});
expect(response.value.raw_result).toEqual({
source_map_text: data.sourceMap.text,
});
});
it.each([
{ ...args, manifest_path: "relative.json" },
{ ...args, script_index: -1 },
{ ...args, source_map: { ...args.source_map, path: "relative.map" } },
{ ...args, source_map: { ...args.source_map, url: "relative.map" } },
{ ...args, generated_position: { line: 0, column: 0 } },
])(
"rejects invalid selected context before acquiring artifacts: %j",
async (input) => {
const response = await new WebSourceLocationService(
{
load: () => {
throw new Error("must not acquire");
},
},
decoder,
).trace(input);
if (response.ok) throw new Error("expected invalid input");
expect(projectAnalysisError(response.error).code).toBe("invalid_request");
},
);
it.each([
"file:///analysis/app.map",
"webpack:///bundle/app.map",
"https://selected-user:selected-value@app.test/maps/app.map",
])(
"retains an absolute inert map context without fetching: %s",
async (url) => {
const fixture = webSourceLocationFixture();
const data = { ...fixture, sourceMap: { ...fixture.sourceMap, url } };
const response = await service(data).trace({
...args,
source_map: { ...args.source_map, url },
});
if (!response.ok) throw response.error;
expect(
webSourceLocationResultSchema.parse(response.value.normalized_result)
.url_context,
).toBe(url);
},
);
it.each(["source", "map", "map-path", "map-url"])(
"rejects changed artifact identity before decoding: %s",
async (variant) => {
const fixture = webSourceLocationFixture();
const data = {
...fixture,
source: variant === "source" ? "different" : fixture.source,
sourceMap: { ...fixture.sourceMap },
};
if (variant === "map") data.sourceMap.text += " ";
if (variant === "map-path") data.sourceMap.file.path = "/other.map";
if (variant === "map-url") data.sourceMap.url = "https://other.test/";
const response = await service(data, {
trace: () => {
throw new Error("must not decode");
},
}).trace(args);
if (response.ok) throw new Error("expected changed identity failure");
expect(response.error._tag).toBe("AnalysisOutputError");
},
);
it.each(["digest", "url", "point"])(
"rejects changed codec identity: %s",
async (variant) => {
const port: WebSourceMapPort = {
trace: async (input) => {
const decoded = await decoder.trace(input);
if (!decoded.ok) return decoded;
const report = decoded.value;
if (variant === "digest") report.source_map_sha256 = "f".repeat(64);
if (variant === "url") report.url_context = "https://other.test/";
if (variant === "point") report.lookup.requested.column += 1;
return Promise.resolve(ok(report));
},
};
const response = await service(undefined, port).trace(args);
if (response.ok) throw new Error("expected changed codec identity failure");
expect(response.error._tag).toBe("AnalysisOutputError");
},
);
it("rejects a generated point outside retained text before decoding", async () => {
const response = await service(undefined, {
trace: () => {
throw new Error("must not decode");
},
}).trace({ ...args, generated_position: { line: 2, column: 0 } });
if (response.ok) throw new Error("expected invalid point");
expect(projectAnalysisError(response.error)).toMatchObject({
code: "invalid_request",
details: { issues: [{ message: expect.stringContaining("outside") }] },
});
});
it("honors cancellation both before acquisition and across decoder completion", async () => {
const first = new AbortController();
first.abort();
const response = await new WebSourceLocationService(
{
load: () => {
throw new Error("must not acquire");
},
},
decoder,
).trace(args, { signal: first.signal });
expect(response.ok).toBe(false);
const controller = new AbortController();
const late = await service(undefined, {
trace: (input) => {
controller.abort();
return decoder.trace(input);
},
}).trace(args, { signal: controller.signal });
if (late.ok) throw new Error("expected cancellation");
expect(late.error._tag).toBe("AnalysisCancelledError");
});

View File

@ -0,0 +1,239 @@
import { createHash } from "node:crypto";
import { isAbsolute } from "node:path";
import { z } from "zod";
import type { AnalysisError } from "../domain/analysisErrorBase.js";
import {
AnalysisCancelledError,
AnalysisInputError,
AnalysisOutputError,
} from "../domain/analysisErrorCore.js";
import { createEvidence, type Evidence } from "../domain/evidence.js";
import { projectInputIssues } from "../domain/inputIssueProjection.js";
import { jsonObjectSchema } from "../domain/jsonValue.js";
import { err, ok, type Result } from "../domain/result.js";
import {
selectedWebScriptArtifactsSchema,
webArtifactFileSchema,
} from "../domain/webScriptArtifacts.js";
import {
WEB_SOURCE_MAP_LIMITS,
webSourceLocationInputSchema,
webSourceLocationResultSchema,
webSourceMapReportSchema,
type WebSourceLocationInput,
type WebSourceMapReport,
} from "../domain/webSourceLocation.js";
import { webSourceOffset } from "../domain/webSourcePosition.js";
import type { ExecutionOptions } from "./AnalysisProvider.js";
import {
capturedWebManifestIdentity,
validateSelectedWebScript,
} from "./ValidateSelectedWebScript.js";
import type {
WebSourceLocationArtifactPort,
WebSourceMapPort,
} from "./WebSourceLocationPorts.js";
const OPERATION = "trace_web_source_location";
const artifactsSchema = selectedWebScriptArtifactsSchema.extend({
sourceMap: z.strictObject({
file: webArtifactFileSchema,
url: z.string().min(1),
text: z.string(),
}),
});
const LIMITATIONS = [
"The source/map pairing and source-map URL context are caller-selected. Deployment authenticity and execution remain unknown.",
"Capture metadata and its Evidence reference are historical context; this trace independently verifies only the selected manifest, script and map bytes.",
"Source names and sourceRoot are reported declarations. Resolved URLs are derived by the pinned upstream codec; no original source is fetched or executed.",
"Embedded source hashes identify the UTF-8 encoding of decoded sourcesContent text, not an independently retained original file. Missing or out-of-range original content positions remain explicit.",
"Lookup returns all segments at the greatest generated position not greater than the selected point, including earlier lines and generated-only segments. A mapped point does not establish an executed range or UI causality.",
"Regular maps and inline indexed sections are supported. External section URLs are unsupported; unknown extensions are retained in raw map text and are not interpreted.",
"Complete evidence has a 4 MiB map, 32 MiB reply, 262144 decoded rows/segments and 64-level section budget. The owned codec has a 20-second deadline, 192 MiB old-generation heap and one V8 worker; cleanup may extend the deadline. V8 heap limits do not establish aggregate RSS limits.",
];
/** Join verified captured bytes with an explicitly selected source-map point. */
export class WebSourceLocationService {
constructor(
readonly artifacts: WebSourceLocationArtifactPort,
readonly decoder: WebSourceMapPort,
) {}
/** Shared CLI/MCP workflow preserves raw declarations and every equal-position match. */
async trace(
rawInput: unknown,
options?: ExecutionOptions,
): Promise<Result<Evidence, AnalysisError>> {
if (options?.signal?.aborted)
return err(new AnalysisCancelledError(OPERATION));
const parsed = webSourceLocationInputSchema.safeParse(rawInput);
if (!parsed.success)
return err(
new AnalysisInputError(
OPERATION,
{ cause: parsed.error },
projectInputIssues(parsed.error.issues, rawInput),
),
);
const input = parsed.data;
const admitted = admitContext(input);
if (!admitted.ok) return admitted;
const loaded = await this.artifacts.load(input, options);
if (!loaded.ok) return loaded;
const verified = artifactsSchema.safeParse(loaded.value);
if (!verified.success)
return invalidOutput(
"Artifact port returned malformed source/map evidence.",
);
const data = verified.data;
const bound = validateSelectedWebScript(input, data, OPERATION);
if (!bound.ok) return bound;
const map = data.sourceMap;
const pairing = verifyPairing(input, data);
if (!pairing.ok) return pairing;
const generatedOffset = pairing.value;
if (options?.signal?.aborted)
return err(new AnalysisCancelledError(OPERATION));
const traced = await this.decoder.trace(
{
text: map.text,
path: map.file.path,
url: map.url,
position: input.generated_position,
},
options,
);
if (!traced.ok) return traced;
const report = verifyReport(input, map.file.sha256, traced.value);
if (!report.ok) return report;
if (options?.signal?.aborted)
return err(new AnalysisCancelledError(OPERATION));
const normalized = webSourceLocationResultSchema.safeParse({
...report.value,
manifest: capturedWebManifestIdentity(data),
source: {
...data.sourceFile,
script_index: input.script_index,
script: bound.value,
},
source_map: { ...map.file, url: map.url, association: "caller-selected" },
generated_offset: generatedOffset,
source_authenticity: "unknown",
execution: "unknown",
limitations: LIMITATIONS,
});
if (!normalized.success) return invalidOutput(normalized.error.message);
return ok(
createEvidence(
{
path: data.sourceFile.path,
sha256: data.sourceFile.sha256,
format: "file",
},
{
id: "rea-web-source-location",
name: "REA captured source-map point trace",
version: "1",
},
{
operation: OPERATION,
parameters: jsonObjectSchema.parse(input),
result: normalized.data,
rawResult: { source_map_text: map.text },
confidence: "derived",
authority: "historical-reference",
limitations: LIMITATIONS,
locations: [
data.sourceFile.path,
data.manifestFile.path,
map.file.path,
].map((path) => ({ kind: "artifact-path", path })),
evidenceLinks:
data.manifest.source_evidence_id === null
? []
: [data.manifest.source_evidence_id],
},
),
);
}
}
const invalidOutput = (message: string): Result<never, AnalysisError> =>
err(new AnalysisOutputError(OPERATION, message));
const invalid = (
path: readonly string[],
message: string,
): Result<never, AnalysisError> =>
err(
new AnalysisInputError(OPERATION, undefined, [
{ path, reason: "invalid_format", message },
]),
);
const admitContext = (
input: WebSourceLocationInput,
): Result<null, AnalysisError> => {
for (const [path, value] of [
["manifest_path", input.manifest_path],
["source_map.path", input.source_map.path],
] as const)
if (!isAbsolute(value))
return invalid(
path.split("."),
"Expected an absolute filesystem path on this host.",
);
if (!URL.canParse(input.source_map.url))
return invalid(
["source_map", "url"],
"Expected an absolute source-map URL context. Select its deployment context explicitly; no URL is fetched.",
);
return ok(null);
};
const verifyPairing = (
input: WebSourceLocationInput,
data: z.output<typeof artifactsSchema>,
): Result<number, AnalysisError> => {
const map = data.sourceMap;
if (
map.file.path !== input.source_map.path ||
map.url !== input.source_map.url ||
Buffer.byteLength(map.text) !== map.file.bytes ||
createHash("sha256").update(map.text).digest("hex") !== map.file.sha256 ||
map.file.bytes > WEB_SOURCE_MAP_LIMITS.mapBytes
)
return invalidOutput(
"Artifact port changed the selected source-map byte identity or URL context.",
);
const generatedOffset = webSourceOffset(
data.source,
input.generated_position,
);
if (generatedOffset === undefined)
return invalid(
["generated_position"],
"Selected generated position is outside the retained script text (one-based lines; zero-based UTF-16 columns).",
);
return ok(generatedOffset);
};
const verifyReport = (
input: WebSourceLocationInput,
sha256: string,
value: unknown,
): Result<WebSourceMapReport, AnalysisError> => {
const report = webSourceMapReportSchema.safeParse(value);
if (!report.success)
return invalidOutput(
"Codec port returned malformed source-map point evidence.",
);
if (
report.data.source_map_sha256 !== sha256 ||
report.data.url_context !== input.source_map.url ||
report.data.lookup.requested.line !== input.generated_position.line ||
report.data.lookup.requested.column !== input.generated_position.column
)
return invalidOutput(
"Codec port changed the selected map, URL context or generated point.",
);
return ok(report.data);
};

View File

@ -1,12 +1,12 @@
import { canonicalDigest } from "../domain/comparisonSemantics.js";
import type { ProviderIdentity } from "./AnalysisProvider.js";
import type { Evidence, EvidenceObservation } from "../domain/evidence.js";
import { createEvidence } from "../domain/evidence.js";
import { canonicalDigest } from "../../domain/comparisonSemantics.js";
import type { ProviderIdentity } from "../AnalysisProvider.js";
import type { Evidence, EvidenceObservation } from "../../domain/evidence.js";
import { createEvidence } from "../../domain/evidence.js";
import type {
ElectronActiveObservationInput,
ElectronActiveObservationResult,
} from "../domain/electronActiveObservation.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
} from "../../domain/electronActiveObservation.js";
import { jsonValueSchema } from "../../domain/jsonValue.js";
type CanonicalElectronActiveObservationInput =
ElectronActiveObservationInput & {

View File

@ -1,10 +1,13 @@
import type { ExecutionOptions, ProviderIdentity } from "./AnalysisProvider.js";
import type { AnalysisError } from "../domain/analysisErrorBase.js";
import type {
ExecutionOptions,
ProviderIdentity,
} from "../AnalysisProvider.js";
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
import type {
ElectronActiveObservationInput,
ElectronActiveObservationResult,
} from "../domain/electronActiveObservation.js";
import type { Result } from "../domain/result.js";
} from "../../domain/electronActiveObservation.js";
import type { Result } from "../../domain/result.js";
/** Provider-neutral boundary for owned Electron runtime experiments. */
export interface ElectronActiveObservationPort {

View File

@ -1,16 +1,16 @@
import { dirname } from "node:path";
import { realpath } from "node:fs/promises";
import type { ExecutionOptions } from "./AnalysisProvider.js";
import type { ExecutionOptions } from "../AnalysisProvider.js";
import type { ElectronActiveObservationPort } from "./ElectronActiveObservationPort.js";
import {
AnalysisCapabilityUnavailableError,
AnalysisInputError,
} from "../domain/analysisErrorCore.js";
import { type AnalysisError } from "../domain/analysisErrorBase.js";
import type { Evidence } from "../domain/evidence.js";
import type { ElectronActiveObservationInput } from "../domain/electronActiveObservation.js";
import { err, type Result } from "../domain/result.js";
} from "../../domain/analysisErrorCore.js";
import { type AnalysisError } from "../../domain/analysisErrorBase.js";
import type { Evidence } from "../../domain/evidence.js";
import type { ElectronActiveObservationInput } from "../../domain/electronActiveObservation.js";
import { err, type Result } from "../../domain/result.js";
import { createElectronActiveEvidence } from "./ElectronActiveEvidence.js";
const OPERATION = "capture_electron_scenario" as const;

View File

@ -1,6 +1,6 @@
import { compareCodePoints } from "../domain/canonicalOrdering.js";
import type { ElectronIpcFinding } from "../domain/electronStaticAnalysisTypes.js";
import type { ElectronBoundarySummary } from "../domain/javascriptApplicationAnalysis.js";
import { compareCodePoints } from "../../domain/canonicalOrdering.js";
import type { ElectronIpcFinding } from "../../domain/electronStaticAnalysisTypes.js";
import type { ElectronBoundarySummary } from "../../domain/javascriptApplicationAnalysis.js";
import type { JavaScriptArtifactAnalysis } from "./JavaScriptArtifactAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import { resolveArtifactPathByContext } from "./JavaScriptArtifactPathResolution.js";

View File

@ -1,6 +1,6 @@
import type { ApplicationNode } from "../domain/javascriptApplicationGraph.js";
import { sha256Text } from "../domain/javascriptStaticAnalysisHelpers.js";
import type { JavaScriptSourceRange } from "../domain/javascriptStaticAnalysisTypes.js";
import type { ApplicationNode } from "../../domain/javascriptApplicationGraph.js";
import { sha256Text } from "../../domain/javascriptStaticAnalysisHelpers.js";
import type { JavaScriptSourceRange } from "../../domain/javascriptStaticAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import type {
JavaScriptArtifactGraphContext,

View File

@ -1,5 +1,5 @@
import type { ApplicationNode } from "../domain/javascriptApplicationGraph.js";
import type { ElectronSenderValidationFinding } from "../domain/electronStaticAnalysisTypes.js";
import type { ApplicationNode } from "../../domain/javascriptApplicationGraph.js";
import type { ElectronSenderValidationFinding } from "../../domain/electronStaticAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import {
artifactLocalIdentity,

View File

@ -1,4 +1,4 @@
import type { ElectronNativeAddonBindingFinding } from "../domain/electronStaticAnalysisTypes.js";
import type { ElectronNativeAddonBindingFinding } from "../../domain/electronStaticAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import {
javascriptAnalysisCoverage,

View File

@ -1,9 +1,9 @@
import type { ApplicationNode } from "../domain/javascriptApplicationGraph.js";
import type { ApplicationNode } from "../../domain/javascriptApplicationGraph.js";
import type {
ElectronBrowserWindowFinding,
ElectronContextBridgeFinding,
ElectronUtilityProcessFinding,
} from "../domain/electronStaticAnalysisTypes.js";
} from "../../domain/electronStaticAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import {
artifactLocalIdentity,

View File

@ -1,16 +1,16 @@
import type { ProviderIdentity } from "./AnalysisProvider.js";
import type { ProviderIdentity } from "../AnalysisProvider.js";
import {
createEvidence,
type Evidence,
type EvidenceObservation,
} from "../domain/evidence.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
} from "../../domain/evidence.js";
import { jsonValueSchema } from "../../domain/jsonValue.js";
import type {
ElectronPageInspection,
ElectronTargetList,
InspectElectronPageInput,
ListElectronTargetsInput,
} from "../domain/electronObservation.js";
} from "../../domain/electronObservation.js";
type ElectronOperation = "list_electron_targets" | "inspect_electron_page";

View File

@ -1,12 +1,15 @@
import type { ExecutionOptions, ProviderIdentity } from "./AnalysisProvider.js";
import type { AnalysisError } from "../domain/analysisErrorBase.js";
import type {
ExecutionOptions,
ProviderIdentity,
} from "../AnalysisProvider.js";
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
import type {
ElectronPageInspection,
ElectronTargetList,
InspectElectronPageInput,
ListElectronTargetsInput,
} from "../domain/electronObservation.js";
import type { Result } from "../domain/result.js";
} from "../../domain/electronObservation.js";
import type { Result } from "../../domain/result.js";
/** Provider-neutral boundary for root-confined Electron file-page observation. */
export interface ElectronObservationPort {

View File

@ -1,13 +1,13 @@
import type { ExecutionOptions } from "./AnalysisProvider.js";
import type { ExecutionOptions } from "../AnalysisProvider.js";
import type { ElectronObservationPort } from "./ElectronObservationPort.js";
import type { Evidence } from "../domain/evidence.js";
import type { Evidence } from "../../domain/evidence.js";
import type {
InspectElectronPageInput,
ListElectronTargetsInput,
} from "../domain/electronObservation.js";
import { AnalysisCapabilityUnavailableError } from "../domain/analysisErrorCore.js";
import { type AnalysisError } from "../domain/analysisErrorBase.js";
import { err, ok, type Result } from "../domain/result.js";
} from "../../domain/electronObservation.js";
import { AnalysisCapabilityUnavailableError } from "../../domain/analysisErrorCore.js";
import { type AnalysisError } from "../../domain/analysisErrorBase.js";
import { err, ok, type Result } from "../../domain/result.js";
import { createElectronEvidence } from "./ElectronEvidence.js";
/** List local file pages exposed by the explicitly selected endpoint. */

View File

@ -5,11 +5,11 @@ import { Ajv2020 } from "ajv/dist/2020.js";
import { expect, it } from "vitest";
import { z } from "zod";
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../domain/javascriptApplicationAnalysis.js";
import { matchJavaScriptApplicationVersions } from "../domain/javascriptApplicationVersionKeys.js";
import { findApplicationFeatureSeeds } from "../domain/javascriptFeatureSeed.js";
import { traceApplicationFeatureInputSchema } from "../domain/javascriptFeatureTraceSchemas.js";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascriptApplicationAnalysis.js";
import { matchJavaScriptApplicationVersions } from "../../domain/javascriptApplicationVersionKeys.js";
import { findApplicationFeatureSeeds } from "../../domain/javascriptFeatureSeed.js";
import { traceApplicationFeatureInputSchema } from "../../domain/javascriptFeatureTraceSchemas.js";
import { analyzeJavaScriptApplication } from "./JavaScriptApplicationService.js";
const analyzeSource = async (

View File

@ -2,13 +2,13 @@ import {
createEvidence,
type Evidence,
type EvidenceObservation,
} from "../domain/evidence.js";
} from "../../domain/evidence.js";
import type {
AnalyzeJavaScriptApplicationInput,
JavaScriptApplicationAnalysisResult,
} from "../domain/javascriptApplicationAnalysis.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import { JAVASCRIPT_APPLICATION_PROVIDER } from "./InvestigationProviders.js";
} from "../../domain/javascriptApplicationAnalysis.js";
import { jsonValueSchema } from "../../domain/jsonValue.js";
import { JAVASCRIPT_APPLICATION_PROVIDER } from "../InvestigationProviders.js";
/** Create Evidence for one deterministic local JavaScript application graph. */
export const createJavaScriptApplicationEvidence = (

View File

@ -2,17 +2,17 @@ import {
JAVASCRIPT_APPLICATION_PROVIDER,
JAVASCRIPT_RUNTIME_RECONCILIATION_PROVIDER,
MANAGED_WORKFLOW_PROVIDER,
} from "./InvestigationProviders.js";
import { parseEvidence, type Evidence } from "../domain/evidence.js";
} from "../InvestigationProviders.js";
import { parseEvidence, type Evidence } from "../../domain/evidence.js";
import {
analyzeJavaScriptApplicationInputSchema,
javascriptApplicationAnalysisResultSchema,
type JavaScriptApplicationAnalysisResult,
} from "../domain/javascriptApplicationAnalysis.js";
import type { JavaScriptApplicationGraph } from "../domain/javascriptApplicationGraph.js";
import type { JavaScriptSemanticGraph } from "../domain/javascriptSemanticGraph.js";
import { javascriptRuntimeReconciliationResultSchema } from "../domain/javascriptRuntimeReconciliationSchemas.js";
import { managedApplicationGraphResultSchema } from "../domain/managedApplicationGraph.js";
} from "../../domain/javascriptApplicationAnalysis.js";
import type { JavaScriptApplicationGraph } from "../../domain/javascriptApplicationGraph.js";
import type { JavaScriptSemanticGraph } from "../../domain/javascriptSemanticGraph.js";
import { javascriptRuntimeReconciliationResultSchema } from "../../domain/javascriptRuntimeReconciliationSchemas.js";
import { managedApplicationGraphResultSchema } from "../../domain/managedApplicationGraph.js";
/** Supported immutable source for an application-level graph workflow. */
export interface ApplicationGraphEvidenceSource {

View File

@ -4,8 +4,8 @@ import { join } from "node:path";
import { describe, expect, it } from "vitest";
import { z } from "zod";
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { projectAnalysisError } from "../../domain/analysisErrorProjection.js";
import { analyzeJavaScriptApplication } from "./JavaScriptApplicationService.js";
describe("JavaScript application failure diagnostics", () => {

View File

@ -1,24 +1,24 @@
import { z } from "zod";
import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js";
import { ArtifactReaderFailure } from "../../artifacts/ArtifactReader.js";
import {
analyzeJavaScriptApplicationInputSchema,
javascriptApplicationAnalysisResultSchema,
} from "../domain/javascriptApplicationAnalysis.js";
} from "../../domain/javascriptApplicationAnalysis.js";
import {
AnalysisInputError,
AnalysisOutputError,
} from "../domain/analysisErrorCore.js";
import { ArtifactOperationError } from "../domain/artifactOperationError.js";
import { type AnalysisError } from "../domain/analysisErrorBase.js";
import type { Evidence } from "../domain/evidence.js";
import { projectInputIssues } from "../domain/inputIssueProjection.js";
import { err, ok, type Result } from "../domain/result.js";
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
import type { ExecutionOptions } from "./AnalysisProvider.js";
} from "../../domain/analysisErrorCore.js";
import { ArtifactOperationError } from "../../domain/artifactOperationError.js";
import { type AnalysisError } from "../../domain/analysisErrorBase.js";
import type { Evidence } from "../../domain/evidence.js";
import { projectInputIssues } from "../../domain/inputIssueProjection.js";
import { err, ok, type Result } from "../../domain/result.js";
import { ProviderAdapterError } from "../../domain/providerAdapterError.js";
import type { ExecutionOptions } from "../AnalysisProvider.js";
import { createJavaScriptApplicationEvidence } from "./JavaScriptApplicationEvidence.js";
import { reconstructJavaScriptArtifact } from "./JavaScriptArtifactReconstruction.js";
import { JAVASCRIPT_APPLICATION_PROVIDER } from "./InvestigationProviders.js";
import { JAVASCRIPT_APPLICATION_PROVIDER } from "../InvestigationProviders.js";
const OPERATION = "analyze_javascript_application" as const;

View File

@ -3,8 +3,8 @@ import { join } from "node:path";
import { expect, it } from "vitest";
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../domain/javascriptApplicationAnalysis.js";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascriptApplicationAnalysis.js";
import { analyzeJavaScriptApplication } from "./JavaScriptApplicationService.js";
const graphIdentities = async (source: string) => {

View File

@ -2,14 +2,14 @@ import {
createEvidence,
type Evidence,
type EvidenceObservation,
} from "../domain/evidence.js";
import type { ApplicationVersionComparisonResult } from "../domain/javascriptApplicationVersionComparisonSchemas.js";
import type { JavaScriptExportShapeComparisonResult } from "../domain/javascriptExportShapeComparisonSchemas.js";
import type { ApplicationFeatureTraceResult } from "../domain/javascriptFeatureTraceSchemas.js";
import type { JavaScriptSemanticTraceResult } from "../domain/javascriptSemanticTraceSchemas.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import type { SourceToBundleComparisonResult } from "../domain/sourceToBundleComparisonSchemas.js";
import { JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER } from "./InvestigationProviders.js";
} from "../../domain/evidence.js";
import type { ApplicationVersionComparisonResult } from "../../domain/javascriptApplicationVersionComparisonSchemas.js";
import type { JavaScriptExportShapeComparisonResult } from "../../domain/javascriptExportShapeComparisonSchemas.js";
import type { ApplicationFeatureTraceResult } from "../../domain/javascriptFeatureTraceSchemas.js";
import type { JavaScriptSemanticTraceResult } from "../../domain/javascriptSemanticTraceSchemas.js";
import { jsonValueSchema } from "../../domain/jsonValue.js";
import type { SourceToBundleComparisonResult } from "../../domain/sourceToBundleComparisonSchemas.js";
import { JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER } from "../InvestigationProviders.js";
/** Create derived Evidence for one bounded application-graph feature trace. */
export const createApplicationFeatureTraceEvidence = (

View File

@ -3,19 +3,19 @@ import { z } from "zod";
import {
AnalysisInputError,
AnalysisProtocolError,
} from "../domain/analysisErrorCore.js";
import { type AnalysisError } from "../domain/analysisErrorBase.js";
import type { Evidence } from "../domain/evidence.js";
import { projectInputIssues } from "../domain/inputIssueProjection.js";
import { compareJavaScriptApplicationVersions } from "../domain/javascriptApplicationVersionComparison.js";
import { compareApplicationVersionsInputSchema } from "../domain/javascriptApplicationVersionComparisonSchemas.js";
import { compareJavaScriptExportShapes } from "../domain/javascriptExportShapeComparison.js";
import { compareJavaScriptExportShapesInputSchema } from "../domain/javascriptExportShapeComparisonSchemas.js";
import { traceApplicationFeature } from "../domain/javascriptFeatureTrace.js";
import { traceApplicationFeatureInputSchema } from "../domain/javascriptFeatureTraceSchemas.js";
import { err, ok, type Result } from "../domain/result.js";
import { compareSourceToBundle } from "../domain/sourceToBundleComparison.js";
import { compareSourceToBundleInputSchema } from "../domain/sourceToBundleComparisonSchemas.js";
} from "../../domain/analysisErrorCore.js";
import { type AnalysisError } from "../../domain/analysisErrorBase.js";
import type { Evidence } from "../../domain/evidence.js";
import { projectInputIssues } from "../../domain/inputIssueProjection.js";
import { compareJavaScriptApplicationVersions } from "../../domain/javascriptApplicationVersionComparison.js";
import { compareApplicationVersionsInputSchema } from "../../domain/javascriptApplicationVersionComparisonSchemas.js";
import { compareJavaScriptExportShapes } from "../../domain/javascriptExportShapeComparison.js";
import { compareJavaScriptExportShapesInputSchema } from "../../domain/javascriptExportShapeComparisonSchemas.js";
import { traceApplicationFeature } from "../../domain/javascriptFeatureTrace.js";
import { traceApplicationFeatureInputSchema } from "../../domain/javascriptFeatureTraceSchemas.js";
import { err, ok, type Result } from "../../domain/result.js";
import { compareSourceToBundle } from "../../domain/sourceToBundleComparison.js";
import { compareSourceToBundleInputSchema } from "../../domain/sourceToBundleComparisonSchemas.js";
import {
parseApplicationGraphEvidence,
parseNativeApplicationEvidence,

View File

@ -1,16 +1,16 @@
import { createHash } from "node:crypto";
import { analyzeParsedJavaScriptStaticSource } from "../domain/javascriptStaticAnalysis.js";
import { analyzeParsedJavaScriptSemantics } from "../domain/javascriptSemanticAnalysis.js";
import { parseJavaScriptSource } from "../domain/javascriptSourceParser.js";
import { hasValidSourceMapContents } from "../domain/sourceMapContents.js";
import { flattenSourceMapLeaves } from "../domain/sourceMapEnvelope.js";
import { analyzeParsedJavaScriptStaticSource } from "../../domain/javascriptStaticAnalysis.js";
import { analyzeParsedJavaScriptSemantics } from "../../domain/javascriptSemanticAnalysis.js";
import { parseJavaScriptSource } from "../../domain/javascriptSourceParser.js";
import { hasValidSourceMapContents } from "../../domain/sourceMapContents.js";
import { flattenSourceMapLeaves } from "../../domain/sourceMapEnvelope.js";
import type {
JavaScriptSourceRange,
JavaScriptSourcePoint,
JavaScriptStaticAnalysis,
} from "../domain/javascriptStaticAnalysisTypes.js";
import { failedJavaScriptStaticAnalysis } from "../domain/javascriptStaticAnalysisHelpers.js";
} from "../../domain/javascriptStaticAnalysisTypes.js";
import { failedJavaScriptStaticAnalysis } from "../../domain/javascriptStaticAnalysisHelpers.js";
import type {
JavaScriptArtifactFile,
JavaScriptArtifactFileSet,

View File

@ -1,8 +1,8 @@
import type {
JavaScriptSourceRange,
JavaScriptStaticAnalysis,
} from "../domain/javascriptStaticAnalysisTypes.js";
import type { JavaScriptSemanticIr } from "../domain/javascriptSemanticIr.js";
} from "../../domain/javascriptStaticAnalysisTypes.js";
import type { JavaScriptSemanticIr } from "../../domain/javascriptSemanticIr.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
interface JavaScriptStructuredObservation {

View File

@ -2,20 +2,20 @@ import { createHash } from "node:crypto";
import { isAbsolute } from "node:path";
import type { Readable } from "node:stream";
import { compareCodePoints } from "../domain/canonicalOrdering.js";
import { AsarArtifactReader } from "../artifacts/AsarArtifactReader.js";
import { compareCodePoints } from "../../domain/canonicalOrdering.js";
import { AsarArtifactReader } from "../../artifacts/AsarArtifactReader.js";
import {
ArtifactPathRegistry,
normalizeArtifactPath,
} from "../artifacts/ArtifactPaths.js";
} from "../../artifacts/ArtifactPaths.js";
import {
ArtifactReaderFailure,
type ArtifactEntry,
type ArtifactReader,
} from "../artifacts/ArtifactReader.js";
import { streamChunkToBuffer } from "../artifacts/StreamBytes.js";
import { hashReadable } from "./ArtifactInventory/hash.js";
import type { ArtifactInventorySnapshot } from "./ArtifactInventory.js";
} from "../../artifacts/ArtifactReader.js";
import { streamChunkToBuffer } from "../../artifacts/StreamBytes.js";
import { hashReadable } from "../ArtifactInventory/hash.js";
import type { ArtifactInventorySnapshot } from "../ArtifactInventory.js";
/** Relevant file categories projected from the complete artifact inventory. */
export type JavaScriptArtifactFileKind =

View File

@ -3,7 +3,7 @@ import {
createJavaScriptApplicationNode,
type ApplicationEdge,
type ApplicationNode,
} from "../domain/javascriptApplicationGraph.js";
} from "../../domain/javascriptApplicationGraph.js";
/** Deduplicate graph entities while retaining distinct evidence observations. */
export class JavaScriptArtifactGraphAccumulator {

View File

@ -1,8 +1,8 @@
import type { ArtifactInventorySnapshot } from "./ArtifactInventory.js";
import type { ArtifactInventorySnapshot } from "../ArtifactInventory.js";
import {
createJavaScriptApplicationGraph,
type JavaScriptApplicationGraph,
} from "../domain/javascriptApplicationGraph.js";
} from "../../domain/javascriptApplicationGraph.js";
import type { JavaScriptArtifactAnalysis } from "./JavaScriptArtifactAnalysisTypes.js";
import type { JavaScriptArtifactFileSet } from "./JavaScriptArtifactFiles.js";
import { JavaScriptArtifactGraphAccumulator } from "./JavaScriptArtifactGraphAccumulator.js";
@ -19,7 +19,7 @@ import {
import {
completeApplicationCoverage,
partialApplicationCoverage,
} from "../domain/javascriptApplicationEvidenceSchemas.js";
} from "../../domain/javascriptApplicationEvidenceSchemas.js";
import {
addJavaScriptArtifactContainers,
addJavaScriptArtifactFiles,

View File

@ -1,5 +1,5 @@
import type { ApplicationNode } from "../domain/javascriptApplicationGraph.js";
import type { JavaScriptBundlerRegistration } from "../domain/javascriptStaticAnalysisTypes.js";
import type { ApplicationNode } from "../../domain/javascriptApplicationGraph.js";
import type { JavaScriptBundlerRegistration } from "../../domain/javascriptStaticAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import {
addAstContainsEdge,

View File

@ -1,11 +1,11 @@
import type { ArtifactInventorySnapshot } from "./ArtifactInventory.js";
import type { ArtifactInventorySnapshot } from "../ArtifactInventory.js";
import {
completeApplicationCoverage,
partialApplicationCoverage,
type ApplicationGraphEvidence,
} from "../domain/javascriptApplicationEvidenceSchemas.js";
import type { ApplicationNode } from "../domain/javascriptApplicationGraph.js";
import type { JavaScriptSourceRange } from "../domain/javascriptStaticAnalysisTypes.js";
} from "../../domain/javascriptApplicationEvidenceSchemas.js";
import type { ApplicationNode } from "../../domain/javascriptApplicationGraph.js";
import type { JavaScriptSourceRange } from "../../domain/javascriptStaticAnalysisTypes.js";
import type { JavaScriptArtifactAnalysis } from "./JavaScriptArtifactAnalysisTypes.js";
import type {
JavaScriptArtifactFile,

View File

@ -6,7 +6,7 @@ import {
type JavaScriptArtifactGraphContext,
} from "./JavaScriptArtifactGraphContext.js";
import { artifactObservationEvidence } from "./JavaScriptArtifactGraphEvidence.js";
import { completeApplicationCoverage } from "../domain/javascriptApplicationEvidenceSchemas.js";
import { completeApplicationCoverage } from "../../domain/javascriptApplicationEvidenceSchemas.js";
import { resolveArtifactPathByContext } from "./JavaScriptArtifactPathResolution.js";
/** Project HTML renderer entrypoints and their local script assets. */

View File

@ -1,5 +1,5 @@
import type { ApplicationGraphEvidence } from "../domain/javascriptApplicationEvidenceSchemas.js";
import type { JavaScriptSourceRange } from "../domain/javascriptStaticAnalysisTypes.js";
import type { ApplicationGraphEvidence } from "../../domain/javascriptApplicationEvidenceSchemas.js";
import type { JavaScriptSourceRange } from "../../domain/javascriptStaticAnalysisTypes.js";
const EXTRACTOR = {
name: "rea-javascript-artifact-reconstruction",

View File

@ -1,5 +1,5 @@
import type { ApplicationNode } from "../domain/javascriptApplicationGraph.js";
import type { JavaScriptStaticAnalysis } from "../domain/javascriptStaticAnalysisTypes.js";
import type { ApplicationNode } from "../../domain/javascriptApplicationGraph.js";
import type { JavaScriptStaticAnalysis } from "../../domain/javascriptStaticAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import {
addStaticInferenceEdge,

View File

@ -1,6 +1,6 @@
import type { ArtifactInventorySnapshot } from "./ArtifactInventory.js";
import type { ApplicationNode } from "../domain/javascriptApplicationGraph.js";
import { completeApplicationCoverage } from "../domain/javascriptApplicationEvidenceSchemas.js";
import type { ArtifactInventorySnapshot } from "../ArtifactInventory.js";
import type { ApplicationNode } from "../../domain/javascriptApplicationGraph.js";
import { completeApplicationCoverage } from "../../domain/javascriptApplicationEvidenceSchemas.js";
import type { JavaScriptArtifactAnalysis } from "./JavaScriptArtifactAnalysisTypes.js";
import type {
JavaScriptArtifactContainer,

View File

@ -6,8 +6,8 @@ import {
} from "./JavaScriptArtifactPathResolution.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import { artifactLocalIdentity } from "./JavaScriptArtifactGraphContext.js";
import { applicationNodeIdentitySchema } from "../domain/javascriptApplicationEvidenceSchemas.js";
import { analyzeJavaScriptStaticSource } from "../domain/javascriptStaticAnalysis.js";
import { applicationNodeIdentitySchema } from "../../domain/javascriptApplicationEvidenceSchemas.js";
import { analyzeJavaScriptStaticSource } from "../../domain/javascriptStaticAnalysis.js";
describe("artifact-local graph identity", () => {
it("preserves complete long namespace and key values", () => {

View File

@ -7,7 +7,7 @@ import {
hasScheme,
looksExternal,
stripQueryAndFragment,
} from "../domain/artifactPathSyntax.js";
} from "../../domain/artifactPathSyntax.js";
type ArtifactPathResolutionContext =
| "package-entrypoint"

View File

@ -1,14 +1,14 @@
import { lstat, realpath } from "node:fs/promises";
import { AsarArtifactReader } from "../artifacts/AsarArtifactReader.js";
import { AsarArtifactReader } from "../../artifacts/AsarArtifactReader.js";
import {
ArtifactReaderFailure,
type ArtifactReader,
} from "../artifacts/ArtifactReader.js";
import { DirectoryArtifactReader } from "../artifacts/DirectoryArtifactReader.js";
import type { JavaScriptApplicationGraph } from "../domain/javascriptApplicationGraph.js";
import type { JavaScriptSemanticGraph } from "../domain/javascriptSemanticGraph.js";
import type { ElectronBoundarySummary } from "../domain/javascriptApplicationAnalysis.js";
} from "../../artifacts/ArtifactReader.js";
import { DirectoryArtifactReader } from "../../artifacts/DirectoryArtifactReader.js";
import type { JavaScriptApplicationGraph } from "../../domain/javascriptApplicationGraph.js";
import type { JavaScriptSemanticGraph } from "../../domain/javascriptSemanticGraph.js";
import type { ElectronBoundarySummary } from "../../domain/javascriptApplicationAnalysis.js";
import { analyzeJavaScriptArtifactFiles } from "./JavaScriptArtifactAnalysis.js";
import { readJavaScriptArtifactFiles } from "./JavaScriptArtifactFiles.js";
import { buildJavaScriptArtifactGraph } from "./JavaScriptArtifactGraphBuilder.js";
@ -16,7 +16,7 @@ import {
javascriptArtifactReconstructionInputSchema,
type JavaScriptArtifactReconstructionInput,
} from "./JavaScriptArtifactReconstructionInput.js";
import { scanCanonicalArtifactInventory } from "./ArtifactInventory.js";
import { scanCanonicalArtifactInventory } from "../ArtifactInventory.js";
import { summarizeElectronBoundaries } from "./ElectronBoundaryAnalysis.js";
import { buildJavaScriptSemanticGraph } from "./JavaScriptSemanticGraphBuilder.js";

View File

@ -5,9 +5,9 @@ import { fileURLToPath, pathToFileURL } from "node:url";
import { parseExpression } from "@babel/parser";
import { describe, expect, it } from "vitest";
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../domain/javascriptApplicationAnalysis.js";
import { staticPath } from "../domain/javascriptStaticAnalysisHelpers.js";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascriptApplicationAnalysis.js";
import { staticPath } from "../../domain/javascriptStaticAnalysisHelpers.js";
import { analyzeJavaScriptApplication } from "./JavaScriptApplicationService.js";
const urlCases = [

View File

@ -1,4 +1,4 @@
import { compareCodePoints } from "../domain/canonicalOrdering.js";
import { compareCodePoints } from "../../domain/canonicalOrdering.js";
import type { JavaScriptJsonModuleObservation } from "./JavaScriptArtifactAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";

View File

@ -1,16 +1,16 @@
import { posix } from "node:path";
import { compareCodePoints } from "../domain/canonicalOrdering.js";
import type { ApplicationNode } from "../domain/javascriptApplicationGraph.js";
import { compareCodePoints } from "../../domain/canonicalOrdering.js";
import type { ApplicationNode } from "../../domain/javascriptApplicationGraph.js";
import {
completeApplicationCoverage,
partialApplicationCoverage,
} from "../domain/javascriptApplicationEvidenceSchemas.js";
} from "../../domain/javascriptApplicationEvidenceSchemas.js";
import type {
JavaScriptModuleOrigin,
JavaScriptSemanticIr,
JavaScriptSemanticModuleLink,
} from "../domain/javascriptSemanticIr.js";
} from "../../domain/javascriptSemanticIr.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import {
addAstContainsEdge,

View File

@ -1,10 +1,10 @@
import type { AnalysisError } from "../domain/analysisErrorBase.js";
import type { JavaScriptRecoveryInput } from "../domain/javascriptRecovery.js";
import type { Result } from "../domain/result.js";
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
import type { JavaScriptRecoveryInput } from "../../domain/javascriptRecovery.js";
import type { Result } from "../../domain/result.js";
import type {
AnalysisExecution,
ExecutionOptions,
} from "./AnalysisProvider.js";
} from "../AnalysisProvider.js";
/** Typed boundary for upstream source recovery without exposing its protocol. */
export interface JavaScriptRecoveryPort {

View File

@ -1,11 +1,11 @@
import { describe, expect, it } from "vitest";
import { AnalysisCapabilityUnavailableError } from "../domain/analysisErrorCore.js";
import { err, ok } from "../domain/result.js";
import { AnalysisCapabilityUnavailableError } from "../../domain/analysisErrorCore.js";
import { err, ok } from "../../domain/result.js";
import type {
JavaScriptRecoveryInput,
JavaScriptRecoveryResult,
} from "../domain/javascriptRecovery.js";
import { createAnalysisExecution } from "./AnalysisProvider.js";
} from "../../domain/javascriptRecovery.js";
import { createAnalysisExecution } from "../AnalysisProvider.js";
import { JavaScriptRecoveryService } from "./JavaScriptRecoveryService.js";
const artifact = { path: "/tmp/bundle.js", sha256: "a".repeat(64), bytes: 20 };

View File

@ -4,17 +4,17 @@ import {
AnalysisCancelledError,
AnalysisInputError,
AnalysisOutputError,
} from "../domain/analysisErrorCore.js";
import type { AnalysisError } from "../domain/analysisErrorBase.js";
import { createEvidence, type Evidence } from "../domain/evidence.js";
} from "../../domain/analysisErrorCore.js";
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
import { createEvidence, type Evidence } from "../../domain/evidence.js";
import {
javascriptRecoveryInputSchema,
javascriptRecoveryResultSchema,
} from "../domain/javascriptRecovery.js";
import { jsonObjectSchema } from "../domain/jsonValue.js";
import { projectInputIssues } from "../domain/inputIssueProjection.js";
import { err, ok, type Result } from "../domain/result.js";
import type { ExecutionOptions } from "./AnalysisProvider.js";
} from "../../domain/javascriptRecovery.js";
import { jsonObjectSchema } from "../../domain/jsonValue.js";
import { projectInputIssues } from "../../domain/inputIssueProjection.js";
import { err, ok, type Result } from "../../domain/result.js";
import type { ExecutionOptions } from "../AnalysisProvider.js";
import type { JavaScriptRecoveryPort } from "./JavaScriptRecoveryPort.js";
const OPERATION = "recover_javascript_sources";

View File

@ -1,7 +1,7 @@
import { describe, expect, it } from "vitest";
import { analyzeJavaScriptSemantics } from "../domain/javascriptSemanticAnalysis.js";
import { completeApplicationCoverage } from "../domain/javascriptApplicationEvidenceSchemas.js";
import { analyzeJavaScriptSemantics } from "../../domain/javascriptSemanticAnalysis.js";
import { completeApplicationCoverage } from "../../domain/javascriptApplicationEvidenceSchemas.js";
import { projectJavaScriptExportReturnShapes } from "./JavaScriptReturnShapeProjection.js";
const projectReturns = (body: string) => {

View File

@ -1,15 +1,15 @@
import { jsonObjectSchema, jsonValueSchema } from "../domain/jsonValue.js";
import { jsonObjectSchema, jsonValueSchema } from "../../domain/jsonValue.js";
import {
partialApplicationCoverage,
truncatedApplicationCoverage,
} from "../domain/javascriptApplicationEvidenceSchemas.js";
} from "../../domain/javascriptApplicationEvidenceSchemas.js";
import type {
JavaScriptSemanticIr,
JavaScriptSemanticCallable,
JavaScriptSemanticModuleLink,
} from "../domain/javascriptSemanticIr.js";
import { flattenSemanticReturnValue } from "../domain/javascriptSemanticReturns.js";
import type { JavaScriptSourceRange } from "../domain/javascriptStaticAnalysisTypes.js";
} from "../../domain/javascriptSemanticIr.js";
import { flattenSemanticReturnValue } from "../../domain/javascriptSemanticReturns.js";
import type { JavaScriptSourceRange } from "../../domain/javascriptStaticAnalysisTypes.js";
import type { JavaScriptArtifactGraphCoverage } from "./JavaScriptArtifactGraphContext.js";
export interface JavaScriptReturnShapeProjection {

View File

@ -1,16 +1,16 @@
import type { ProviderIdentity } from "./AnalysisProvider.js";
import type { ProviderIdentity } from "../AnalysisProvider.js";
import {
createEvidence,
type Evidence,
type EvidenceObservation,
} from "../domain/evidence.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
} from "../../domain/evidence.js";
import { jsonValueSchema } from "../../domain/jsonValue.js";
import type {
JavaScriptRuntimeObservation,
JavaScriptRuntimeTargetList,
ListJavaScriptRuntimeTargetsInput,
ObserveJavaScriptRuntimeInput,
} from "../domain/javascriptRuntimeObservation.js";
} from "../../domain/javascriptRuntimeObservation.js";
type RuntimeObservationOperation =
| "list_javascript_runtime_targets"

View File

@ -1,12 +1,15 @@
import type { ExecutionOptions, ProviderIdentity } from "./AnalysisProvider.js";
import type {
ExecutionOptions,
ProviderIdentity,
} from "../AnalysisProvider.js";
import type {
JavaScriptRuntimeObservation,
JavaScriptRuntimeTargetList,
ListJavaScriptRuntimeTargetsInput,
ObserveJavaScriptRuntimeInput,
} from "../domain/javascriptRuntimeObservation.js";
import type { AnalysisError } from "../domain/analysisErrorBase.js";
import type { Result } from "../domain/result.js";
} from "../../domain/javascriptRuntimeObservation.js";
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
import type { Result } from "../../domain/result.js";
/** Provider-neutral boundary for passive Node/Electron Inspector observation. */
export interface JavaScriptRuntimeObservationPort {

View File

@ -1,14 +1,14 @@
import type { ExecutionOptions } from "./AnalysisProvider.js";
import type { ExecutionOptions } from "../AnalysisProvider.js";
import type { JavaScriptRuntimeObservationPort } from "./JavaScriptRuntimeObservationPort.js";
import { createJavaScriptRuntimeObservationEvidence } from "./JavaScriptRuntimeObservationEvidence.js";
import type { Evidence } from "../domain/evidence.js";
import { AnalysisCapabilityUnavailableError } from "../domain/analysisErrorCore.js";
import { type AnalysisError } from "../domain/analysisErrorBase.js";
import type { Evidence } from "../../domain/evidence.js";
import { AnalysisCapabilityUnavailableError } from "../../domain/analysisErrorCore.js";
import { type AnalysisError } from "../../domain/analysisErrorBase.js";
import type {
ListJavaScriptRuntimeTargetsInput,
ObserveJavaScriptRuntimeInput,
} from "../domain/javascriptRuntimeObservation.js";
import { err, ok, type Result } from "../domain/result.js";
} from "../../domain/javascriptRuntimeObservation.js";
import { err, ok, type Result } from "../../domain/result.js";
/** List targets exposed by the explicitly selected loopback Inspector. */
export const listJavaScriptRuntimeTargets = async (

View File

@ -2,13 +2,13 @@ import {
createEvidence,
type Evidence,
type EvidenceObservation,
} from "../domain/evidence.js";
} from "../../domain/evidence.js";
import type {
JavaScriptRuntimeReconciliationResult,
ReconcileJavaScriptRuntimeInput,
} from "../domain/javascriptRuntimeReconciliationSchemas.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import { JAVASCRIPT_RUNTIME_RECONCILIATION_PROVIDER } from "./InvestigationProviders.js";
} from "../../domain/javascriptRuntimeReconciliationSchemas.js";
import { jsonValueSchema } from "../../domain/jsonValue.js";
import { JAVASCRIPT_RUNTIME_RECONCILIATION_PROVIDER } from "../InvestigationProviders.js";
/** Create derived Evidence for one exact set of static/runtime inputs. */
export const createJavaScriptRuntimeReconciliationEvidence = (

View File

@ -4,13 +4,13 @@ import { z } from "zod";
import {
AnalysisInputError,
AnalysisProtocolError,
} from "../domain/analysisErrorCore.js";
import { type AnalysisError } from "../domain/analysisErrorBase.js";
import type { Evidence } from "../domain/evidence.js";
import { projectInputIssues } from "../domain/inputIssueProjection.js";
import { reconcileJavaScriptRuntime } from "../domain/javascriptRuntimeReconciliation.js";
import { reconcileJavaScriptRuntimeInputSchema } from "../domain/javascriptRuntimeReconciliationSchemas.js";
import { err, ok, type Result } from "../domain/result.js";
} from "../../domain/analysisErrorCore.js";
import { type AnalysisError } from "../../domain/analysisErrorBase.js";
import type { Evidence } from "../../domain/evidence.js";
import { projectInputIssues } from "../../domain/inputIssueProjection.js";
import { reconcileJavaScriptRuntime } from "../../domain/javascriptRuntimeReconciliation.js";
import { reconcileJavaScriptRuntimeInputSchema } from "../../domain/javascriptRuntimeReconciliationSchemas.js";
import { err, ok, type Result } from "../../domain/result.js";
import { createJavaScriptRuntimeReconciliationEvidence } from "./JavaScriptRuntimeReconciliationEvidence.js";
const OPERATION = "reconcile_javascript_runtime" as const;

View File

@ -1,9 +1,9 @@
import { createJavaScriptSemanticGraphUnknown } from "../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticGraphNode } from "../domain/javascriptSemanticGraph.js";
import { createJavaScriptSemanticGraphUnknown } from "../../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticGraphNode } from "../../domain/javascriptSemanticGraph.js";
import type {
JavaScriptSemanticEventOperation,
JavaScriptSemanticTimerOperation,
} from "../domain/javascriptSemanticIr.js";
} from "../../domain/javascriptSemanticIr.js";
import {
addSemanticGraphNode,
addSemanticGraphRelation,

View File

@ -3,8 +3,8 @@ import { expect, it } from "vitest";
import { buildJavaScriptSemanticGraph } from "./JavaScriptSemanticGraphBuilder.js";
import type { JavaScriptArtifactAnalysis } from "./JavaScriptArtifactAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import { queryJavaScriptSemanticGraph } from "../domain/javascriptSemanticQuery.js";
import { analyzeJavaScriptSemantics } from "../domain/javascriptSemanticAnalysis.js";
import { queryJavaScriptSemanticGraph } from "../../domain/javascriptSemanticQuery.js";
import { analyzeJavaScriptSemantics } from "../../domain/javascriptSemanticAnalysis.js";
const SHA256 = "a".repeat(64);
const GRAPH_ID = `jag_${"b".repeat(64)}`;

View File

@ -2,17 +2,17 @@ import {
createJavaScriptSemanticGraph,
type JavaScriptSemanticGraph,
type JavaScriptSemanticGraphNode,
} from "../domain/javascriptSemanticGraph.js";
} from "../../domain/javascriptSemanticGraph.js";
import {
JAVASCRIPT_SEMANTIC_RELATION_FAMILIES,
JAVASCRIPT_SEMANTIC_RELATION_FAMILY,
} from "../domain/javascriptSemanticGraphSchemas.js";
} from "../../domain/javascriptSemanticGraphSchemas.js";
import type {
JavaScriptSemanticCallArgument,
JavaScriptSemanticIr,
} from "../domain/javascriptSemanticIr.js";
import { sourceRangesEqual as rangesEqual } from "../domain/javascriptStaticAnalysisHelpers.js";
import type { JavaScriptApplicationGraph } from "../domain/javascriptApplicationGraph.js";
} from "../../domain/javascriptSemanticIr.js";
import { sourceRangesEqual as rangesEqual } from "../../domain/javascriptStaticAnalysisHelpers.js";
import type { JavaScriptApplicationGraph } from "../../domain/javascriptApplicationGraph.js";
import type { JavaScriptArtifactAnalysis } from "./JavaScriptArtifactAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import {

View File

@ -1,9 +1,9 @@
import { createJavaScriptSemanticGraphUnknown } from "../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticGraphNode } from "../domain/javascriptSemanticGraph.js";
import { createJavaScriptSemanticGraphUnknown } from "../../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticGraphNode } from "../../domain/javascriptSemanticGraph.js";
import type {
JavaScriptSemanticChildProcessInteraction,
JavaScriptSemanticChildProcessSpawn,
} from "../domain/javascriptSemanticIr.js";
} from "../../domain/javascriptSemanticIr.js";
import {
addSemanticGraphNode,
addSemanticGraphRelation,

View File

@ -1,17 +1,17 @@
import type { JavaScriptApplicationGraph } from "../domain/javascriptApplicationGraph.js";
import type { JsonValue } from "../domain/jsonValue.js";
import { javascriptDisplayText } from "../domain/javascriptAstValues.js";
import type { JavaScriptApplicationGraph } from "../../domain/javascriptApplicationGraph.js";
import type { JsonValue } from "../../domain/jsonValue.js";
import { javascriptDisplayText } from "../../domain/javascriptAstValues.js";
import {
createJavaScriptSemanticGraphNode,
createJavaScriptSemanticGraphRelation,
type JavaScriptSemanticGraphNode,
} from "../domain/javascriptSemanticGraph.js";
import type { ApplicationGraphEvidence } from "../domain/javascriptApplicationEvidenceSchemas.js";
} from "../../domain/javascriptSemanticGraph.js";
import type { ApplicationGraphEvidence } from "../../domain/javascriptApplicationEvidenceSchemas.js";
import type {
JavaScriptSemanticGraphRelation,
JavaScriptSemanticGraphUnknown,
} from "../domain/javascriptSemanticGraphSchemas.js";
import type { JavaScriptSourceRange } from "../domain/javascriptStaticAnalysisTypes.js";
} from "../../domain/javascriptSemanticGraphSchemas.js";
import type { JavaScriptSourceRange } from "../../domain/javascriptStaticAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import {
inferredSemanticEvidence,

View File

@ -1,10 +1,10 @@
import { createJavaScriptSemanticGraphUnknown } from "../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticGraphNode } from "../domain/javascriptSemanticGraph.js";
import { createJavaScriptSemanticGraphUnknown } from "../../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticGraphNode } from "../../domain/javascriptSemanticGraph.js";
import type {
JavaScriptSemanticBoundaryOperation,
JavaScriptSemanticConfigurationOperation,
JavaScriptSemanticRequestOperation,
} from "../domain/javascriptSemanticIr.js";
} from "../../domain/javascriptSemanticIr.js";
import {
addSemanticGraphNode,
addSemanticGraphRelation,

View File

@ -1,6 +1,6 @@
import type { ApplicationGraphEvidence } from "../domain/javascriptApplicationEvidenceSchemas.js";
import type { JavaScriptSemanticGraphNode } from "../domain/javascriptSemanticGraph.js";
import type { JavaScriptSourceRange } from "../domain/javascriptStaticAnalysisTypes.js";
import type { ApplicationGraphEvidence } from "../../domain/javascriptApplicationEvidenceSchemas.js";
import type { JavaScriptSemanticGraphNode } from "../../domain/javascriptSemanticGraph.js";
import type { JavaScriptSourceRange } from "../../domain/javascriptStaticAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
const INFERENCE_LIMITATION =

View File

@ -2,8 +2,8 @@ import {
createJavaScriptSemanticFingerprint,
type JavaScriptSemanticGraph,
type JavaScriptSemanticGraphNode,
} from "../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticIr } from "../domain/javascriptSemanticIr.js";
} from "../../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticIr } from "../../domain/javascriptSemanticIr.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import { observedSemanticEvidence } from "./JavaScriptSemanticGraphEvidence.js";

View File

@ -1,8 +1,8 @@
import { createJavaScriptSemanticGraphUnknown } from "../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticGraphNode } from "../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticIr } from "../domain/javascriptSemanticIr.js";
import { sourceRangesEqual } from "../domain/javascriptStaticAnalysisHelpers.js";
import type { JavaScriptSourceRange } from "../domain/javascriptStaticAnalysisTypes.js";
import { createJavaScriptSemanticGraphUnknown } from "../../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticGraphNode } from "../../domain/javascriptSemanticGraph.js";
import type { JavaScriptSemanticIr } from "../../domain/javascriptSemanticIr.js";
import { sourceRangesEqual } from "../../domain/javascriptStaticAnalysisHelpers.js";
import type { JavaScriptSourceRange } from "../../domain/javascriptStaticAnalysisTypes.js";
import type { JavaScriptArtifactFile } from "./JavaScriptArtifactFiles.js";
import {
addSemanticGraphNode,

Some files were not shown because too many files have changed in this diff Show More