[PR #1424] [MERGED] fix(javascript): unify package resolution and resolve exact exports subpaths #2876

Closed
opened 2026-10-17 21:11:18 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1424
Author: @AWUQAQ
Created: 10/10/2026
Status: ✅ Merged
Merged: 10/10/2026
Merged by: @morluto

Base: main ← Head: fix/javascript-resolve-package-export-subpaths


📝 Commits (3)

  • 4dcf30c fix(javascript): resolve exact package export subpaths
  • dbe4b9d fix(javascript): unify package path resolution
  • b1f1409 fix(javascript): merge main and retain shared path normalization

📊 Changes

3 files changed (+868 additions, -304 deletions)

View changed files

📝 src/application/javascript/JavaScriptArtifactPathResolution.test.ts (+386 -1)
📝 src/application/javascript/JavaScriptArtifactPathResolution.ts (+322 -303)
➕ tests/acceptance/applications/packageSubpathsCli.test.ts (+160 -0)

📄 Description

Summary

Resolve exact package exports subpaths and preserve the consumer's original declaration and Evidence. Package roots and subpaths now share one metadata reader, exports selector, and directory lookup. Fixes #1365.

Problem and expected behavior

An import of fixture/parser remained external even when the inventoried package exported ./parser. The initial implementation also replaced the caller's declaration/context with the selected target, skipped nearer packages without metadata, ignored directory main entrypoints, and accepted trailing-slash exports keys that Node refuses.

The graph now selects the nearest same-container package, resolves its exact exported file or directory entrypoint as appropriate, and retains the original declaration and source provenance. Missing, blocked, and unexported targets carry explicit outcomes without falling through to another package.

Change and scope

  • Unify package-root and subpath metadata/exports resolution. Remove duplicate parsers, selectors, mode flags, conversion wrappers, and the separate subpath fallback implementation; no compatibility shims remain.
  • Detect package directories from same-container inventory descendants, including packages without package.json.
  • Use shared file/directory lookup when exports are absent, including nested directory main fields. Nested directory exports do not control a filesystem lookup.
  • Resolve exports targets as exact URL paths without extension/index fallback. Exact matching excludes trailing-slash and wildcard keys.
  • Attach the original declaration and context once at the public resolution boundary.

Wildcard expansion and package-private # imports remain outside this change.

Contract and boundary impact

  • Semantic owner and earliest changed stage: application-layer static JavaScript artifact path resolution, before graph relationship and Electron role construction.
  • CLI and MCP/tool-catalog contract: existing schemas and tool names remain unchanged; both adapters expose corrected resolution and provenance.
  • Provider, bridge, target-format, or platform compatibility: static JavaScript artifacts; no native provider changes.
  • Evidence, artifact, provenance, or reconstruction contract: preserve source declaration/context, artifact digest, source range, and container identity through target selection.
  • Process execution, authorization, cleanup, or containment impact: production resolution reads the inventoried map only; artifact-root confinement remains enforced.
  • Generated metadata, package, or installation impact: none.

Evidence and regression coverage

  • Tests added or updated: exact exports coverage plus same/foreign-container metadata-less packages, sibling-prefix decoys, malformed/unavailable nested metadata, and cycles. New public CLI and stdio MCP tests compare package selection with Node and verify source digests, source ranges, and Electron preload identity.

  • Base reproduction: the reviewed PR head 4dcf30c87 exhibited all four additional failures; the added fixtures exercise their observable outcomes.

  • User-visible CLI/MCP output: exported/parser resolves to node_modules/exported/parser.cjs; preload observations retain declared_path: "exported/parser" and resolution_context: "module-specifier". Unexported/trailing-slash keys stay external; a missing selected export stays not-found.

  • Remaining proof gaps: final validation ran on macOS with Node 24.18.0; Windows was not rerun. Large inventories can incur additional scanning for packages without metadata; no global cache was introduced.

  • Observed, derived, and inferred claims remain distinguishable.

  • Artifact identity, source provenance, and failed attempts remain preserved.

  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • npm run test:local -- <all 18 JavaScript application test files> — 284 passed.
  • npm run test:focused -- tests/boundary/javascript/packageConditionalExports.test.ts — 44 passed, including real Node import/require comparisons.
  • npm run test:focused -- tests/acceptance/applications/packageSubpathsCli.test.ts — 2 passed through the packaged CLI and stdio MCP server.
  • npm run check — passed typecheck, lint, formatting, knip, metadata, module boundaries, and architecture guards; lint reported 485 warnings and zero errors.
  • npm run verify:test-discovery — 701 test files discovered exactly once.
  • git diff --check — passed.

Compatibility, safety, and release

  • Breaking changes or migration steps: none; the existing public result contract is retained. Superseded internal implementations are removed.
  • Real Hopper/Ghidra, browser, or OS coverage: macOS CLI/MCP and Node resolver validation; native providers and browser runtime execution are outside this static analysis change.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: caller input and source evidence remain intact; same-container checks and path confinement are preserved.

Review checklist

  • This PR addresses a concrete problem or an agreed enhancement.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1424 **Author:** [@AWUQAQ](https://github.com/AWUQAQ) **Created:** 10/10/2026 **Status:** ✅ Merged **Merged:** 10/10/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/javascript-resolve-package-export-subpaths` --- ### 📝 Commits (3) - [`4dcf30c`](https://github.com/morluto/rea/commit/4dcf30c87f91a05eb6e6c9e41dea6742e9d05a84) fix(javascript): resolve exact package export subpaths - [`dbe4b9d`](https://github.com/morluto/rea/commit/dbe4b9d9365a794b6b1c4bed123d7bf7cd0f200c) fix(javascript): unify package path resolution - [`b1f1409`](https://github.com/morluto/rea/commit/b1f140972afd128f99f65252ebdc97e9376a055e) fix(javascript): merge main and retain shared path normalization ### 📊 Changes **3 files changed** (+868 additions, -304 deletions) <details> <summary>View changed files</summary> 📝 `src/application/javascript/JavaScriptArtifactPathResolution.test.ts` (+386 -1) 📝 `src/application/javascript/JavaScriptArtifactPathResolution.ts` (+322 -303) ➕ `tests/acceptance/applications/packageSubpathsCli.test.ts` (+160 -0) </details> ### 📄 Description ## Summary Resolve exact package exports subpaths and preserve the consumer's original declaration and Evidence. Package roots and subpaths now share one metadata reader, exports selector, and directory lookup. Fixes #1365. ## Problem and expected behavior An import of `fixture/parser` remained external even when the inventoried package exported `./parser`. The initial implementation also replaced the caller's declaration/context with the selected target, skipped nearer packages without metadata, ignored directory `main` entrypoints, and accepted trailing-slash exports keys that Node refuses. The graph now selects the nearest same-container package, resolves its exact exported file or directory entrypoint as appropriate, and retains the original declaration and source provenance. Missing, blocked, and unexported targets carry explicit outcomes without falling through to another package. ## Change and scope - Unify package-root and subpath metadata/exports resolution. Remove duplicate parsers, selectors, mode flags, conversion wrappers, and the separate subpath fallback implementation; no compatibility shims remain. - Detect package directories from same-container inventory descendants, including packages without `package.json`. - Use shared file/directory lookup when exports are absent, including nested directory `main` fields. Nested directory exports do not control a filesystem lookup. - Resolve exports targets as exact URL paths without extension/index fallback. Exact matching excludes trailing-slash and wildcard keys. - Attach the original declaration and context once at the public resolution boundary. Wildcard expansion and package-private `#` imports remain outside this change. ## Contract and boundary impact - Semantic owner and earliest changed stage: application-layer static JavaScript artifact path resolution, before graph relationship and Electron role construction. - CLI and MCP/tool-catalog contract: existing schemas and tool names remain unchanged; both adapters expose corrected resolution and provenance. - Provider, bridge, target-format, or platform compatibility: static JavaScript artifacts; no native provider changes. - Evidence, artifact, provenance, or reconstruction contract: preserve source declaration/context, artifact digest, source range, and container identity through target selection. - Process execution, authorization, cleanup, or containment impact: production resolution reads the inventoried map only; artifact-root confinement remains enforced. - Generated metadata, package, or installation impact: none. ## Evidence and regression coverage - Tests added or updated: exact exports coverage plus same/foreign-container metadata-less packages, sibling-prefix decoys, malformed/unavailable nested metadata, and cycles. New public CLI and stdio MCP tests compare package selection with Node and verify source digests, source ranges, and Electron preload identity. - Base reproduction: the reviewed PR head `4dcf30c87` exhibited all four additional failures; the added fixtures exercise their observable outcomes. - User-visible CLI/MCP output: `exported/parser` resolves to `node_modules/exported/parser.cjs`; preload observations retain `declared_path: "exported/parser"` and `resolution_context: "module-specifier"`. Unexported/trailing-slash keys stay external; a missing selected export stays not-found. - Remaining proof gaps: final validation ran on macOS with Node 24.18.0; Windows was not rerun. Large inventories can incur additional scanning for packages without metadata; no global cache was introduced. - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - `npm run test:local -- <all 18 JavaScript application test files>` — 284 passed. - `npm run test:focused -- tests/boundary/javascript/packageConditionalExports.test.ts` — 44 passed, including real Node import/require comparisons. - `npm run test:focused -- tests/acceptance/applications/packageSubpathsCli.test.ts` — 2 passed through the packaged CLI and stdio MCP server. - `npm run check` — passed typecheck, lint, formatting, knip, metadata, module boundaries, and architecture guards; lint reported 485 warnings and zero errors. - `npm run verify:test-discovery` — 701 test files discovered exactly once. - `git diff --check` — passed. ## Compatibility, safety, and release - Breaking changes or migration steps: none; the existing public result contract is retained. Superseded internal implementations are removed. - Real Hopper/Ghidra, browser, or OS coverage: macOS CLI/MCP and Node resolver validation; native providers and browser runtime execution are outside this static analysis change. - Package or release metadata impact: none. - Security, privacy, process, or containment review: caller input and source evidence remain intact; same-container checks and path confinement are preserved. ## Review checklist - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:11:18 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2876
No description provided.