[PR #1239] [MERGED] fix(javascript): classify application input selection failures by cause #2742

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

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1239
Author: @kaoru0822-kitauji
Created: 10/9/2026
Status: ✅ Merged
Merged: 10/9/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/javascript-input-selection-errors


📝 Commits (2)

  • 0a14bbb fix(javascript): classify application input selection failures by cause
  • d186ca7 test(javascript): expect the invalid input_path code in the streamed CLI failure test

📊 Changes

8 files changed (+188 additions, -20 deletions)

View changed files

📝 src/application/javascript/JavaScriptApplicationService.test.ts (+6 -3)
📝 src/application/javascript/JavaScriptApplicationService.ts (+13 -1)
📝 src/application/javascript/JavaScriptArtifactReconstruction.ts (+55 -9)
📝 tests/acceptance/applications/javascriptCancellationCli.test.ts (+2 -2)
📝 tests/boundary/cli/javascriptApplicationJsonOutput.test.ts (+2 -2)
📝 tests/boundary/cli/javascriptApplicationProgress.test.ts (+1 -1)
➕ tests/boundary/filesystem/javascriptApplicationInputSelection.test.ts (+102 -0)
📝 tests/boundary/filesystem/javascriptArtifactReconstruction.test.ts (+7 -2)

📄 Description

Problem

analyze_javascript_application / rea analyze-javascript-application reports every problem with the caller's input selection as a damaged artifact, so the advice never matches the cause. Measured on main (macOS, CLI; MCP returns the same projection):

Selection main result
missing input_path artifact_operation_failed / io: "Artifact could not be read or written. Check file access and try again." There is no path and no reason in details.
unreadable selected directory (mode 000) same io failure; EACCES appears only inside details.detail
a regular file that is neither a directory nor an .asar (e.g. a Mach-O) artifact_operation_failed / format: "Artifact is invalid or has changed. Get a fresh copy and try again."
--artifact-format asar (MCP format) on a directory, or directory on an .asar same "get a fresh copy" format failure

None of these artifacts is damaged, so "get a fresh copy" and "check file access" are the wrong advice.

Change

JavaScriptArtifactReconstruction classifies the selection before inventory starts:

Selection Result
missing (ENOENT/ENOTDIR on the selected path) invalid_request; an issue on input_path: "No file or directory exists at the selected input path (ENOENT): "
unreadable (EACCES/EPERM on the selected path) access_denied with path and system_code, like other selected-input readers (CaptureFailures, SignatureTargetBinding)
not a directory and not an .asar unsupported_target at the caller's path; remediation: "Select an extracted application directory, an app bundle, or an .asar file such as Contents/Resources/app.asar."
requested format contradicts the selection invalid_request; an issue on format with expected: ["auto", <observed>]

JavaScriptApplicationService passes these three typed errors through instead of wrapping them in ProviderAdapterError. Failures inside a selected artifact (cancellation, inventory/format/integrity, mid-analysis filesystem errors) keep their existing classification. Schemas are unchanged.

After the change (CLI JSON, abbreviated):

missing      → {"code":"invalid_request","details":{"issues":[{"path":["input_path"],"reason":"invalid_value","message":"No file or directory exists at the selected input path (ENOENT): …/nope"}]}}
Mach-O file  → {"code":"unsupported_target","message":"Unsupported target for analyze_javascript_application at …/ls: JavaScript application analysis accepts only a directory or an .asar file","remediation":{"action":"Select an extracted application directory, an app bundle, or an .asar file such as Contents/Resources/app.asar."}}
mode 000 dir → {"code":"access_denied","details":{"path":"…/locked","system_code":"EACCES","boundary":"filesystem-read"}}
format asar  → {"code":"invalid_request","details":{"issues":[{"path":["format"],"reason":"invalid_value","message":"Requested asar input, but the selected input is a directory: …/app","expected":["auto","directory"]}]}}

Tests

  • New tests/boundary/filesystem/javascriptApplicationInputSelection.test.ts covers all four selections through the service projection. All 5 cases fail on main. The access-denied case is skipped on Windows and when running as root.
  • Five existing tests used a missing path or a contradicting format only as a convenient failure, and pinned the old artifact codes incidentally. Their intent is kept: a typed failure in streamed JSON output; a nonzero exit for a streamed failure (tests/acceptance/applications/javascriptCancellationCli.test.ts); non-terminal progress on failure; the path retained in the format diagnostic; a missing selection kept distinct from an engine failure. Only the expected codes changed.

Verification

  • Every test file that exercises analyze_javascript_application or reconstructJavaScriptArtifact, plus the application acceptance and composition suites (55 files, 458 tests), passed after npm run build:cached. npm run check:changed also passed (typecheck, lint, 176 affected tests).
  • Real CLI for the four selections, shown above. rea analyze <directory> still produces Evidence.
  • Real MCP tools/call analyze_javascript_application returns the same unsupported_target and invalid_request projections.

No Hopper or Ghidra verification was needed; neither provider is involved.

🤖 Generated with Claude Code


🔄 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/1239 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/9/2026 **Status:** ✅ Merged **Merged:** 10/9/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/javascript-input-selection-errors` --- ### 📝 Commits (2) - [`0a14bbb`](https://github.com/morluto/rea/commit/0a14bbbf05e0e61c98e06326fe7136e52fa4fb3c) fix(javascript): classify application input selection failures by cause - [`d186ca7`](https://github.com/morluto/rea/commit/d186ca7e41928fc2748de2631f5cb43115776571) test(javascript): expect the invalid input_path code in the streamed CLI failure test ### 📊 Changes **8 files changed** (+188 additions, -20 deletions) <details> <summary>View changed files</summary> 📝 `src/application/javascript/JavaScriptApplicationService.test.ts` (+6 -3) 📝 `src/application/javascript/JavaScriptApplicationService.ts` (+13 -1) 📝 `src/application/javascript/JavaScriptArtifactReconstruction.ts` (+55 -9) 📝 `tests/acceptance/applications/javascriptCancellationCli.test.ts` (+2 -2) 📝 `tests/boundary/cli/javascriptApplicationJsonOutput.test.ts` (+2 -2) 📝 `tests/boundary/cli/javascriptApplicationProgress.test.ts` (+1 -1) ➕ `tests/boundary/filesystem/javascriptApplicationInputSelection.test.ts` (+102 -0) 📝 `tests/boundary/filesystem/javascriptArtifactReconstruction.test.ts` (+7 -2) </details> ### 📄 Description ## Problem `analyze_javascript_application` / `rea analyze-javascript-application` reports every problem with the caller's input selection as a damaged artifact, so the advice never matches the cause. Measured on `main` (macOS, CLI; MCP returns the same projection): | Selection | `main` result | | --- | --- | | missing `input_path` | `artifact_operation_failed` / `io`: "Artifact could not be read or written. Check file access and try again." There is no path and no reason in `details`. | | unreadable selected directory (mode 000) | same `io` failure; `EACCES` appears only inside `details.detail` | | a regular file that is neither a directory nor an `.asar` (e.g. a Mach-O) | `artifact_operation_failed` / `format`: "Artifact is invalid or has changed. Get a fresh copy and try again." | | `--artifact-format asar` (MCP `format`) on a directory, or `directory` on an `.asar` | same "get a fresh copy" `format` failure | None of these artifacts is damaged, so "get a fresh copy" and "check file access" are the wrong advice. ## Change `JavaScriptArtifactReconstruction` classifies the selection before inventory starts: | Selection | Result | | --- | --- | | missing (`ENOENT`/`ENOTDIR` on the selected path) | `invalid_request`; an issue on `input_path`: "No file or directory exists at the selected input path (ENOENT): <path>" | | unreadable (`EACCES`/`EPERM` on the selected path) | `access_denied` with `path` and `system_code`, like other selected-input readers (`CaptureFailures`, `SignatureTargetBinding`) | | not a directory and not an `.asar` | `unsupported_target` at the caller's path; remediation: "Select an extracted application directory, an app bundle, or an .asar file such as Contents/Resources/app.asar." | | requested format contradicts the selection | `invalid_request`; an issue on `format` with `expected: ["auto", <observed>]` | `JavaScriptApplicationService` passes these three typed errors through instead of wrapping them in `ProviderAdapterError`. Failures inside a selected artifact (cancellation, inventory/format/integrity, mid-analysis filesystem errors) keep their existing classification. Schemas are unchanged. After the change (CLI JSON, abbreviated): ``` missing → {"code":"invalid_request","details":{"issues":[{"path":["input_path"],"reason":"invalid_value","message":"No file or directory exists at the selected input path (ENOENT): …/nope"}]}} Mach-O file → {"code":"unsupported_target","message":"Unsupported target for analyze_javascript_application at …/ls: JavaScript application analysis accepts only a directory or an .asar file","remediation":{"action":"Select an extracted application directory, an app bundle, or an .asar file such as Contents/Resources/app.asar."}} mode 000 dir → {"code":"access_denied","details":{"path":"…/locked","system_code":"EACCES","boundary":"filesystem-read"}} format asar → {"code":"invalid_request","details":{"issues":[{"path":["format"],"reason":"invalid_value","message":"Requested asar input, but the selected input is a directory: …/app","expected":["auto","directory"]}]}} ``` ## Tests - New `tests/boundary/filesystem/javascriptApplicationInputSelection.test.ts` covers all four selections through the service projection. All 5 cases fail on `main`. The access-denied case is skipped on Windows and when running as root. - Five existing tests used a missing path or a contradicting format only as a convenient failure, and pinned the old artifact codes incidentally. Their intent is kept: a typed failure in streamed JSON output; a nonzero exit for a streamed failure (`tests/acceptance/applications/javascriptCancellationCli.test.ts`); non-terminal progress on failure; the path retained in the format diagnostic; a missing selection kept distinct from an engine failure. Only the expected codes changed. ## Verification - Every test file that exercises `analyze_javascript_application` or `reconstructJavaScriptArtifact`, plus the application acceptance and composition suites (55 files, 458 tests), passed after `npm run build:cached`. `npm run check:changed` also passed (typecheck, lint, 176 affected tests). - Real CLI for the four selections, shown above. `rea analyze <directory>` still produces Evidence. - Real MCP `tools/call analyze_javascript_application` returns the same `unsupported_target` and `invalid_request` projections. No Hopper or Ghidra verification was needed; neither provider is involved. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:09:43 +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#2742
No description provided.