Skip to content

🐛 fix(ipc): resolve socket path mismatch for CLI inside .app bundle#52

Merged
vaayne merged 1 commit intovaayne:mainfrom
0xbentang:fix/ipc-socket-path
Apr 12, 2026
Merged

🐛 fix(ipc): resolve socket path mismatch for CLI inside .app bundle#52
vaayne merged 1 commit intovaayne:mainfrom
0xbentang:fix/ipc-socket-path

Conversation

@0xbentang
Copy link
Copy Markdown
Contributor

Fix: mori CLI IPC socket path mismatch

Problem

The mori CLI could not communicate with the running Mori.app. Commands like mori project list failed with:

Launching Mori.app…
Error: Mori.app launched but IPC socket not ready after 10s.

The IPC server was healthy (direct socket connection worked), but the CLI was looking for the socket in the wrong directory.

Root Cause

MoriPaths.isBundledApp relied on Bundle.main.bundlePath.hasSuffix(".app") to decide whether to use the production directory (~/Library/Application Support/Mori/) or the dev directory (~/Library/Application Support/Mori-Dev/).

This works for the main app executable (/Applications/Mori.app/Contents/MacOS/Mori), where Bundle.main.bundlePath correctly returns /Applications/Mori.app. But for the mori CLI binary at /Applications/Mori.app/Contents/MacOS/bin/mori, macOS sets Bundle.main.bundlePath to the directory containing the executable (.../Contents/MacOS/bin/), not the .app bundle root. Since that path does not end with .app, isBundledApp returned false, and the CLI resolved the socket to ~/Library/Application Support/Mori-Dev/mori.sock — which does not exist.

Fix

Restructured isBundledApp to also walk up the executable path (with symlinks resolved) looking for a .app ancestor directory. This correctly identifies both the main app and secondary executables (like the CLI) shipped inside the bundle, while still excluding dev builds in .build, .build-cli, and DerivedData.

Changes

  • MoriIPC/MoriPaths.swift — Rewrote isBundledApp to check executable path ancestors in addition to Bundle.main.bundlePath. Extracted isInAppBundle(_:) and isInBuildDirectory(_:) as internal helpers.
  • MoriIPCTests/main.swift — Added 14 assertions covering isInAppBundle, isInBuildDirectory, env-var overrides, and the bug scenario (CLI at Contents/MacOS/bin/mori).

Testing

mise run test     # All 1,115 assertions pass (76 IPC, 678 Core, 249 Tmux, 64 Persistence, 48 Keybindings)

The mori CLI binary lives at Contents/MacOS/bin/mori inside Mori.app.
For this secondary executable, Bundle.main.bundlePath returns the
directory (Contents/MacOS/bin/), not the .app bundle root — so the
old hasSuffix(".app") check failed and the CLI looked for the
socket at ~/Library/Application Support/Mori-Dev/mori.sock instead
of ~/Library/Application Support/Mori/mori.sock.

Fix MoriPaths.isBundledApp to walk up the executable's resolved path
looking for a .app ancestor, correctly identifying both the main app
and any CLI tools shipped inside the bundle. Adds 14 test assertions
covering bundle detection, build-directory exclusion, and env overrides.
Copy link
Copy Markdown
Owner

@vaayne vaayne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I verified the bundle-path root cause, checked the updated MoriPaths detection logic, and ran mise run test:ipc locally. The fix correctly handles secondary executables inside Mori.app while preserving dev-build exclusion behavior.

@vaayne vaayne merged commit 1a4dc59 into vaayne:main Apr 12, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants