[PR #2426] [MERGED] fix(setup): resolve the configuration MSIX Claude Desktop reads #5220

Closed
opened 2026-10-31 01:04:54 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

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

Base: main ← Head: fix/claude-desktop-msix-config


📝 Commits (7)

  • 70ffd9c fix(setup): resolve the configuration MSIX Claude Desktop reads
  • 15bfc83 docs(setup): record the verified MSIX Claude Desktop registration
  • 59fc6ed Merge main into fix/claude-desktop-msix-config
  • b38ac5f fix(setup): reconcile MSIX configuration and uninstall ownership
  • 7d5d33e style(setup): format MSIX review corrections
  • 68a3ae0 fix(setup): carry the admitted legacy path through uninstall removal
  • 593318d test(setup): split MSIX Claude Desktop lifecycle cases under the function length limit

📊 Changes

21 files changed (+1764 additions, -124 deletions)

View changed files

📝 docs/client-configuration.md (+65 -0)
📝 docs/installation.md (+3 -1)
📝 scripts/verify-package-environment.mjs (+1 -0)
📝 scripts/verify-package-update.mjs (+1 -0)
📝 scripts/verify-published-package.mjs (+1 -0)
📝 scripts/verify-windows-package.mjs (+1 -0)
➕ src/application/ClaudeDesktopConfigLocation.test.ts (+341 -0)
➕ src/application/ClaudeDesktopConfigLocation.ts (+199 -0)
📝 src/application/ClientRegistrationStatus.ts (+26 -22)
➕ src/application/MsixPackageStorage.ts (+187 -0)
📝 src/application/Setup.configuration.test.ts (+117 -1)
📝 src/application/Setup.fixture.ts (+1 -0)
📝 src/application/SetupClientConfiguration.ts (+31 -1)
📝 src/application/SetupClients.ts (+2 -0)
📝 src/application/SetupHost.ts (+30 -4)
📝 src/application/SetupPlan.ts (+60 -28)
📝 src/application/SetupTypes.ts (+8 -1)
📝 src/application/SupportedClients.ts (+120 -33)
📝 src/application/Uninstall.ts (+157 -33)
➕ tests/boundary/filesystem/claudeDesktopClientConfiguration.test.ts (+412 -0)

...and 1 more files

📄 Description

Summary

On Windows, rea setup, rea doctor and rea uninstall for claude_desktop always used %APPDATA%\Claude\claude_desktop_config.json. The MSIX build of Claude Desktop (package family Claude_pzs8sxrjxfjjc) does not read that file once it has saved its own configuration. It reads its package-private copy at %LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json. Setup and doctor now resolve the file the installed app actually reads. When they cannot establish it, they report that instead of guessing.

No existing issue; the failure was observed on a Windows 11 host with rea-agents 6.4.0 (details below).

Problem and expected behavior

Observed with rea-agents 6.4.0 on Windows 11 with the MSIX build 2.31226.1.0:

  • False healthy. Setup run from an ordinary process created a new 422-byte %APPDATA%\Claude\claude_desktop_config.json containing only mcpServers.rea, and rea doctor --client claude_desktop reported healthy: true. The packaged app never reads that file, so the registration had no effect. The leftover file is still on that host, while the private copy has no mcpServers.
  • Change lost. Setup run from a process the app started (for example a Claude Desktop Code tab terminal) sees AppData redirected into the package, so it wrote the right file. The running app then rewrote the configuration from memory within seconds and dropped the change.
  • Invisible launcher. npm install -g from such a process lands in …\LocalCache\Roaming\npm. A registration pointing at the %APPDATA%\npm\…\rea.mjs path then exists only inside the package's view.

Expected:

  • Setup, doctor and uninstall act on the file the installed Claude Desktop reads.
  • An unknown identity stays unknown instead of being treated as %APPDATA%.
  • Setup does not report as configured a change the running app will overwrite.

Change and scope

  • One owner for the location. supportedClients() resolves the Claude Desktop location once through ClaudeDesktopConfigLocation. Setup, doctor, uninstall and update maintenance all consume that result.
    • Without Packages\Claude_pzs8sxrjxfjjc, the location is unchanged (%APPDATA%).
    • With it, the location is the private copy when that exists, else the %APPDATA% file the package still reads, else a new private copy.
    • The publisher ID pzs8sxrjxfjjc is the MSIX hash of the package publisher CN="Anthropic, PBC", …; it was recomputed from the installed package's publisher string.
  • Fail closed.
    • A Claude_<publisher ID> package from another publisher, or an unreadable Packages directory or private path, becomes configPathError. There is no fallback to %APPDATA%.
  • Process view. The resolver compares one of the package's private files (the configuration first) with its %APPDATA% path through fs.realpathSync.native. This is observed to work although such processes report no package identity (GetCurrentPackageFullName returned APPMODEL_ERROR_NO_PACKAGE).
    • redirected: the running package started this process.
    • direct: it did not.
    • unknown: nothing could be compared.
  • Setup and uninstall gates.
    • Setup and uninstall refuse to change Claude Desktop's configuration unless the view is direct. Uninstall applies this only when REA's entry is present.
    • From a redirected view, they also refuse writes under %APPDATA%/%LOCALAPPDATA% for other clients (VS Code, Trae, Devin, Hermes) and for skill destinations. Those writes would land in the package's private storage.
    • Doctor stays read-only and reads the same file from either kind of process.
  • Launcher check. Setup refuses to register a launcher whose canonical path lies in any MSIX package's LocalCache. Both sides of the comparison are canonicalized, so short-name or junctioned profiles still match.
  • Disclosure.
    • Setup plans state which file the MSIX package reads and that Claude Desktop must be fully quit. The quit note appears for every platform.
    • Doctor's claude_desktop remediation says the same.
  • Target re-check. Configuration fails with target_changed when the package began reading its private copy after the plan chose the %APPDATA% file, for example when it saved its settings on quit.
  • Uninstall cleanup. Uninstall removes REA's entry from both the private copy and the %APPDATA% file, which includes entries written there by earlier releases.

Not included:

  • Detection of a non-MSIX Claude Desktop installed alongside the MSIX package. That layout was not available to verify; this is documented as a limitation.
  • No process enumeration and no Win32 package APIs.

Contract and boundary impact

  • Semantic owner and earliest changed stage:
    • src/application/ClaudeDesktopConfigLocation.ts, consumed only through supportedClients().
    • src/application/MsixPackageStorage.ts owns the package-storage facts.
  • Contribution scope fit and linked maintainer decision: an ordinary fix within the existing setup/doctor/uninstall boundary; no new provider or target interaction. A scope decision is not applicable.
  • CLI and MCP/tool-catalog contract:
    • Setup JSON clientStates[].client may now include msixPackage and quitBeforeSetup.
    • clients.<id>.reason gains target_changed.
    • Plan detail and doctor remediation text changed for claude_desktop.
    • Setup can now return needs_human from the redirected and unknown views described above.
    • No MCP tool or schema changes.
  • Provider, bridge, target-format, or platform compatibility: location resolution changes on Windows only. The quit note is added on all platforms.
  • Evidence, artifact, provenance, or reconstruction contract: none.
  • Target selection, authority, upstream behavior, and cleanup details: setup writes keep the existing backup, atomic write and readback; the backup now sits next to the private copy. Uninstall removes only REA-owned entries.
  • Generated metadata, package, or installation impact: none; the product catalog fields are unchanged and npm run docs:check passed.

Expected effects:

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration. (Which client configuration file setup and uninstall change on Windows, plus new refusals.)
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated:
    • tests/boundary/filesystem/claudeDesktopClientConfiguration.test.ts (11 tests, real temp APPDATA/LOCALAPPDATA, MSIX and non-MSIX layouts). It covers:
      • the AppData layout without package storage;
      • the private copy;
      • read-through to AppData before a private copy exists;
      • creating the private copy;
      • an unrecognized publisher (doctor, detection, setup);
      • a setup write that preserves unrelated keys, with the backup next to the private copy;
      • an AppData-only rea reported as missing (the false healthy case);
      • the redirected-view refusal;
      • target_changed;
      • uninstall refusing an unknown view;
      • uninstall cleaning both files.
    • src/application/ClaudeDesktopConfigLocation.test.ts (14 tests, injected filesystem) covers:
      • redirected, direct and unknown views, including detection through a non-configuration private file;
      • unreadable storage;
      • case-insensitive family matching;
      • the launcher check with canonical and short-name package paths;
      • redirected-write targeting.
    • src/application/Setup.configuration.test.ts adds plan disclosure, the AppData-redirect refusal, and the launcher refusal.
  • Base reproduction or other evidence:
    • The false healthy case was reported on 6.4.0.
    • On the same host, an out-of-container read showed the 422-byte %APPDATA% file holding only mcpServers.rea, a separate inode from the private copy.
    • The new boundary tests were not executed against the base revision. On base, supportedClients() returns the %APPDATA% path, so the private-copy expectations would not hold.
  • User-visible CLI output: from the real host.
    • Inside a Claude Desktop Code tab terminal, setup --client claude_desktop --dry-run --json:
      status: needs_human
      remediation: Claude Desktop: This process was started from Claude Desktop's MSIX package Claude_pzs8sxrjxfjjc: its AppData is redirected into that package, so Claude Desktop is running and would overwrite C:\Users\<user>\AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json from memory. Quit Claude Desktop fully, then rerun setup from a terminal that Claude Desktop did not start.
      
    • The same terminal with --client vscode:
      remediation: This process was started by MSIX package Claude_pzs8sxrjxfjjc, which redirects its writes under C:\Users\<user>\AppData\Roaming and C:\Users\<user>\AppData\Local into the package's private storage. Changes to C:\Users\<user>\AppData\Roaming\Code\User\mcp.json would not reach the files other apps read. Rerun setup from a terminal that this app did not start.
      
    • From an ordinary process outside the package:
      • doctor --client claude_desktop --json reports state: "missing" at the private copy instead of the earlier false healthy result.
      • setup --client claude_desktop --client vscode --dry-run --json plans configure_client:claude_desktop update on the private copy and configure_client:vscode create, with processView: "direct".
  • Real setup write (added after opening): on the same host, rea setup --client claude_desktop was run from an ordinary PowerShell with Claude Desktop fully quit, and the plan was approved. Results:
    • It wrote mcpServers.rea to the package-private copy and kept preferences and coworkUserFilesPath.
    • After Claude Desktop restarted, the entry was still present.
    • doctor --client claude_desktop --json reported healthy: true and aligned at the private copy.
    • Claude Desktop's %LOCALAPPDATA%\Claude\logs\mcp-server-rea.log shows Server started and connected successfully, then initialize, notifications/initialized and tools/list. mcp.log shows the server answering tools/list and prompts/list.
  • Remaining proof gaps:
    • Uninstall against the real app is unverified.
    • The "rewrite from memory" behavior is verified only on the Windows MSIX build; the quit note on other platforms is guidance.
    • The redirect gate for other AppData clients is inferred from documented MSIX write virtualization and the observed npm behavior; it was not tested per client.

For evidence-bearing changes: not applicable.

Validation performed

  • npx tsc --noEmit: passed.
  • npx oxlint <changed files>: no new warnings in changed code. Remaining warnings in touched files were pre-existing (file length and complexity).
  • npm run verify:module-boundaries: passed.
  • npm run docs:check: passed.
  • npm run test:local -- src/application/ClaudeDesktopConfigLocation.test.ts src/application/Setup.configuration.test.ts: 32 passed.
  • npm run test:focused -- tests/boundary/filesystem/claudeDesktopClientConfiguration.test.ts: 11 passed.
  • npx vitest run --project services on Windows: 802 passed, 6 failed. The same 6 fail on the unmodified base on this Windows host (LinuxHopper, MacHopper, Setup.planning skill-path tests).
  • npm run test:focused over 22 related client/setup/uninstall boundary files on Windows: 331 passed, 47 failed. The identical 47 tests fail on the unmodified base on this Windows host (symlink and POSIX-path tests); no new failures.
  • Pre-push npm run check:fast: passed.
  • Real host (Windows 11, Claude Desktop MSIX 2.31226.1.0): read-only doctor and setup --dry-run inside and outside the package, as shown above.
  • Real host: rea setup --client claude_desktop from an ordinary terminal with the app quit. The app restarted, the registration persisted, doctor reported healthy: true, and the MCP log shows REA answering tools/list.

Compatibility, safety, and release

  • Breaking changes or migration steps: none intended.
    • On Windows with the MSIX build, setup now writes the package-private copy instead of %APPDATA%, which is the fix.
    • Setup run from a terminal that Claude Desktop started now refuses the Claude Desktop write and writes under %APPDATA%/%LOCALAPPDATA% instead of silently writing files that do not take effect.
  • Real Hopper/Ghidra, browser, or OS coverage: Windows 11 only: read-only checks plus one real setup write that Claude Desktop loaded, as above. Uninstall was not run against the real app. macOS and Linux location resolution is unchanged; only the quit note is new there.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: no process launch or network access.
    • The new probes are readdir/lstat/realpath on the package storage paths.
    • Writes keep the existing backup, atomic replacement and readback.
    • Error messages include local paths, as existing configuration errors already do.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • 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.

🤖 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/2426 **Author:** [@FeeHaard](https://github.com/FeeHaard) **Created:** 10/13/2026 **Status:** ✅ Merged **Merged:** 10/13/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/claude-desktop-msix-config` --- ### 📝 Commits (7) - [`70ffd9c`](https://github.com/morluto/rea/commit/70ffd9c94700482f37d0b1301c706dbc41cbd11f) fix(setup): resolve the configuration MSIX Claude Desktop reads - [`15bfc83`](https://github.com/morluto/rea/commit/15bfc83daa975f80730561fc2307d3a9e6f70d08) docs(setup): record the verified MSIX Claude Desktop registration - [`59fc6ed`](https://github.com/morluto/rea/commit/59fc6ed93362762569f63f4790bdf467ceaf9a3b) Merge main into fix/claude-desktop-msix-config - [`b38ac5f`](https://github.com/morluto/rea/commit/b38ac5fbaf52852c8df124c5f37cbaec107c47e9) fix(setup): reconcile MSIX configuration and uninstall ownership - [`7d5d33e`](https://github.com/morluto/rea/commit/7d5d33e2feccb9d02d2769b0afda4013c72ad92b) style(setup): format MSIX review corrections - [`68a3ae0`](https://github.com/morluto/rea/commit/68a3ae0bd7bf1691bf393dabd9de25cd50a7ce54) fix(setup): carry the admitted legacy path through uninstall removal - [`593318d`](https://github.com/morluto/rea/commit/593318df40a570364947cb3a020ce7116e6cfeed) test(setup): split MSIX Claude Desktop lifecycle cases under the function length limit ### 📊 Changes **21 files changed** (+1764 additions, -124 deletions) <details> <summary>View changed files</summary> 📝 `docs/client-configuration.md` (+65 -0) 📝 `docs/installation.md` (+3 -1) 📝 `scripts/verify-package-environment.mjs` (+1 -0) 📝 `scripts/verify-package-update.mjs` (+1 -0) 📝 `scripts/verify-published-package.mjs` (+1 -0) 📝 `scripts/verify-windows-package.mjs` (+1 -0) ➕ `src/application/ClaudeDesktopConfigLocation.test.ts` (+341 -0) ➕ `src/application/ClaudeDesktopConfigLocation.ts` (+199 -0) 📝 `src/application/ClientRegistrationStatus.ts` (+26 -22) ➕ `src/application/MsixPackageStorage.ts` (+187 -0) 📝 `src/application/Setup.configuration.test.ts` (+117 -1) 📝 `src/application/Setup.fixture.ts` (+1 -0) 📝 `src/application/SetupClientConfiguration.ts` (+31 -1) 📝 `src/application/SetupClients.ts` (+2 -0) 📝 `src/application/SetupHost.ts` (+30 -4) 📝 `src/application/SetupPlan.ts` (+60 -28) 📝 `src/application/SetupTypes.ts` (+8 -1) 📝 `src/application/SupportedClients.ts` (+120 -33) 📝 `src/application/Uninstall.ts` (+157 -33) ➕ `tests/boundary/filesystem/claudeDesktopClientConfiguration.test.ts` (+412 -0) _...and 1 more files_ </details> ### 📄 Description ## Summary On Windows, `rea setup`, `rea doctor` and `rea uninstall` for `claude_desktop` always used `%APPDATA%\Claude\claude_desktop_config.json`. The MSIX build of Claude Desktop (package family `Claude_pzs8sxrjxfjjc`) does not read that file once it has saved its own configuration. It reads its package-private copy at `%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json`. Setup and doctor now resolve the file the installed app actually reads. When they cannot establish it, they report that instead of guessing. No existing issue; the failure was observed on a Windows 11 host with rea-agents 6.4.0 (details below). ## Problem and expected behavior Observed with rea-agents 6.4.0 on Windows 11 with the MSIX build 2.31226.1.0: - **False healthy.** Setup run from an ordinary process created a new 422-byte `%APPDATA%\Claude\claude_desktop_config.json` containing only `mcpServers.rea`, and `rea doctor --client claude_desktop` reported `healthy: true`. The packaged app never reads that file, so the registration had no effect. The leftover file is still on that host, while the private copy has no `mcpServers`. - **Change lost.** Setup run from a process the app started (for example a Claude Desktop Code tab terminal) sees AppData redirected into the package, so it wrote the right file. The running app then rewrote the configuration from memory within seconds and dropped the change. - **Invisible launcher.** `npm install -g` from such a process lands in `…\LocalCache\Roaming\npm`. A registration pointing at the `%APPDATA%\npm\…\rea.mjs` path then exists only inside the package's view. Expected: - Setup, doctor and uninstall act on the file the installed Claude Desktop reads. - An unknown identity stays unknown instead of being treated as `%APPDATA%`. - Setup does not report as configured a change the running app will overwrite. ## Change and scope - **One owner for the location.** `supportedClients()` resolves the Claude Desktop location once through `ClaudeDesktopConfigLocation`. Setup, doctor, uninstall and update maintenance all consume that result. - Without `Packages\Claude_pzs8sxrjxfjjc`, the location is unchanged (`%APPDATA%`). - With it, the location is the private copy when that exists, else the `%APPDATA%` file the package still reads, else a new private copy. - The publisher ID `pzs8sxrjxfjjc` is the MSIX hash of the package publisher `CN="Anthropic, PBC", …`; it was recomputed from the installed package's publisher string. - **Fail closed.** - A `Claude_<publisher ID>` package from another publisher, or an unreadable `Packages` directory or private path, becomes `configPathError`. There is no fallback to `%APPDATA%`. - **Process view.** The resolver compares one of the package's private files (the configuration first) with its `%APPDATA%` path through `fs.realpathSync.native`. This is observed to work although such processes report no package identity (`GetCurrentPackageFullName` returned `APPMODEL_ERROR_NO_PACKAGE`). - `redirected`: the running package started this process. - `direct`: it did not. - `unknown`: nothing could be compared. - **Setup and uninstall gates.** - Setup and uninstall refuse to change Claude Desktop's configuration unless the view is `direct`. Uninstall applies this only when REA's entry is present. - From a redirected view, they also refuse writes under `%APPDATA%`/`%LOCALAPPDATA%` for other clients (VS Code, Trae, Devin, Hermes) and for skill destinations. Those writes would land in the package's private storage. - Doctor stays read-only and reads the same file from either kind of process. - **Launcher check.** Setup refuses to register a launcher whose canonical path lies in any MSIX package's `LocalCache`. Both sides of the comparison are canonicalized, so short-name or junctioned profiles still match. - **Disclosure.** - Setup plans state which file the MSIX package reads and that Claude Desktop must be fully quit. The quit note appears for every platform. - Doctor's `claude_desktop` remediation says the same. - **Target re-check.** Configuration fails with `target_changed` when the package began reading its private copy after the plan chose the `%APPDATA%` file, for example when it saved its settings on quit. - **Uninstall cleanup.** Uninstall removes REA's entry from both the private copy and the `%APPDATA%` file, which includes entries written there by earlier releases. Not included: - Detection of a non-MSIX Claude Desktop installed alongside the MSIX package. That layout was not available to verify; this is documented as a limitation. - No process enumeration and no Win32 package APIs. ## Contract and boundary impact - **Semantic owner and earliest changed stage:** - `src/application/ClaudeDesktopConfigLocation.ts`, consumed only through `supportedClients()`. - `src/application/MsixPackageStorage.ts` owns the package-storage facts. - **Contribution scope fit and linked maintainer decision:** an ordinary fix within the existing setup/doctor/uninstall boundary; no new provider or target interaction. A scope decision is not applicable. - **CLI and MCP/tool-catalog contract:** - Setup JSON `clientStates[].client` may now include `msixPackage` and `quitBeforeSetup`. - `clients.<id>.reason` gains `target_changed`. - Plan `detail` and doctor `remediation` text changed for `claude_desktop`. - Setup can now return `needs_human` from the redirected and unknown views described above. - No MCP tool or schema changes. - **Provider, bridge, target-format, or platform compatibility:** location resolution changes on Windows only. The quit note is added on all platforms. - **Evidence, artifact, provenance, or reconstruction contract:** none. - **Target selection, authority, upstream behavior, and cleanup details:** setup writes keep the existing backup, atomic write and readback; the backup now sits next to the private copy. Uninstall removes only REA-owned entries. - **Generated metadata, package, or installation impact:** none; the product catalog fields are unchanged and `npm run docs:check` passed. Expected effects: - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [x] Change process memory, registers, files, or configuration. (Which client configuration file setup and uninstall change on Windows, plus new refusals.) - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - **Tests added or updated:** - `tests/boundary/filesystem/claudeDesktopClientConfiguration.test.ts` (11 tests, real temp `APPDATA`/`LOCALAPPDATA`, MSIX and non-MSIX layouts). It covers: - the AppData layout without package storage; - the private copy; - read-through to AppData before a private copy exists; - creating the private copy; - an unrecognized publisher (doctor, detection, setup); - a setup write that preserves unrelated keys, with the backup next to the private copy; - an AppData-only `rea` reported as missing (the false healthy case); - the redirected-view refusal; - `target_changed`; - uninstall refusing an unknown view; - uninstall cleaning both files. - `src/application/ClaudeDesktopConfigLocation.test.ts` (14 tests, injected filesystem) covers: - redirected, direct and unknown views, including detection through a non-configuration private file; - unreadable storage; - case-insensitive family matching; - the launcher check with canonical and short-name package paths; - redirected-write targeting. - `src/application/Setup.configuration.test.ts` adds plan disclosure, the AppData-redirect refusal, and the launcher refusal. - **Base reproduction or other evidence:** - The false healthy case was reported on 6.4.0. - On the same host, an out-of-container read showed the 422-byte `%APPDATA%` file holding only `mcpServers.rea`, a separate inode from the private copy. - The new boundary tests were not executed against the base revision. On base, `supportedClients()` returns the `%APPDATA%` path, so the private-copy expectations would not hold. - **User-visible CLI output:** from the real host. - Inside a Claude Desktop Code tab terminal, `setup --client claude_desktop --dry-run --json`: ``` status: needs_human remediation: Claude Desktop: This process was started from Claude Desktop's MSIX package Claude_pzs8sxrjxfjjc: its AppData is redirected into that package, so Claude Desktop is running and would overwrite C:\Users\<user>\AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json from memory. Quit Claude Desktop fully, then rerun setup from a terminal that Claude Desktop did not start. ``` - The same terminal with `--client vscode`: ``` remediation: This process was started by MSIX package Claude_pzs8sxrjxfjjc, which redirects its writes under C:\Users\<user>\AppData\Roaming and C:\Users\<user>\AppData\Local into the package's private storage. Changes to C:\Users\<user>\AppData\Roaming\Code\User\mcp.json would not reach the files other apps read. Rerun setup from a terminal that this app did not start. ``` - From an ordinary process outside the package: - `doctor --client claude_desktop --json` reports `state: "missing"` at the private copy instead of the earlier false healthy result. - `setup --client claude_desktop --client vscode --dry-run --json` plans `configure_client:claude_desktop update` on the private copy and `configure_client:vscode create`, with `processView: "direct"`. - **Real setup write (added after opening):** on the same host, `rea setup --client claude_desktop` was run from an ordinary PowerShell with Claude Desktop fully quit, and the plan was approved. Results: - It wrote `mcpServers.rea` to the package-private copy and kept `preferences` and `coworkUserFilesPath`. - After Claude Desktop restarted, the entry was still present. - `doctor --client claude_desktop --json` reported `healthy: true` and `aligned` at the private copy. - Claude Desktop's `%LOCALAPPDATA%\Claude\logs\mcp-server-rea.log` shows `Server started and connected successfully`, then `initialize`, `notifications/initialized` and `tools/list`. `mcp.log` shows the server answering `tools/list` and `prompts/list`. - **Remaining proof gaps:** - Uninstall against the real app is unverified. - The "rewrite from memory" behavior is verified only on the Windows MSIX build; the quit note on other platforms is guidance. - The redirect gate for other AppData clients is inferred from documented MSIX write virtualization and the observed npm behavior; it was not tested per client. For evidence-bearing changes: not applicable. ## Validation performed - `npx tsc --noEmit`: passed. - `npx oxlint <changed files>`: no new warnings in changed code. Remaining warnings in touched files were pre-existing (file length and complexity). - `npm run verify:module-boundaries`: passed. - `npm run docs:check`: passed. - `npm run test:local -- src/application/ClaudeDesktopConfigLocation.test.ts src/application/Setup.configuration.test.ts`: 32 passed. - `npm run test:focused -- tests/boundary/filesystem/claudeDesktopClientConfiguration.test.ts`: 11 passed. - `npx vitest run --project services` on Windows: 802 passed, 6 failed. The same 6 fail on the unmodified base on this Windows host (`LinuxHopper`, `MacHopper`, `Setup.planning` skill-path tests). - `npm run test:focused` over 22 related client/setup/uninstall boundary files on Windows: 331 passed, 47 failed. The identical 47 tests fail on the unmodified base on this Windows host (symlink and POSIX-path tests); no new failures. - Pre-push `npm run check:fast`: passed. - Real host (Windows 11, Claude Desktop MSIX 2.31226.1.0): read-only `doctor` and `setup --dry-run` inside and outside the package, as shown above. - Real host: `rea setup --client claude_desktop` from an ordinary terminal with the app quit. The app restarted, the registration persisted, doctor reported `healthy: true`, and the MCP log shows REA answering `tools/list`. ## Compatibility, safety, and release - **Breaking changes or migration steps:** none intended. - On Windows with the MSIX build, setup now writes the package-private copy instead of `%APPDATA%`, which is the fix. - Setup run from a terminal that Claude Desktop started now refuses the Claude Desktop write and writes under `%APPDATA%`/`%LOCALAPPDATA%` instead of silently writing files that do not take effect. - **Real Hopper/Ghidra, browser, or OS coverage:** Windows 11 only: read-only checks plus one real setup write that Claude Desktop loaded, as above. Uninstall was not run against the real app. macOS and Linux location resolution is unchanged; only the quit note is new there. - **Package or release metadata impact:** none. - **Security, privacy, process, or containment review:** no process launch or network access. - The new probes are `readdir`/`lstat`/`realpath` on the package storage paths. - Writes keep the existing backup, atomic replacement and readback. - Error messages include local paths, as existing configuration errors already do. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [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. 🤖 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-31 01:04:54 +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#5220
No description provided.