Skip to content

start: restore original CWD before importing server bundle#924

Open
mattst88 wants to merge 1 commit into
mksglu:mainfrom
mattst88:fix-start-mjs-chdir
Open

start: restore original CWD before importing server bundle#924
mattst88 wants to merge 1 commit into
mksglu:mainfrom
mattst88:fix-start-mjs-chdir

Conversation

@mattst88

@mattst88 mattst88 commented Jul 6, 2026

Copy link
Copy Markdown

Fixes #923.

start.mjs calls process.chdir(__dirname) early in startup for self-heal path operations, but never restores the original working directory. This causes VTE-based terminals (gnome-terminal, etc.) to open new tabs in the plugin cache directory instead of the user's project directory.

VTE determines the "open new tab here" directory by reading /proc/<pid>/cwd of the foreground process group. The MCP server subprocess inherits the terminal's process group, so its CWD is what the terminal sees.

ES module import() resolves relative to import.meta.url, not process.cwd(), so restoring the original CWD before the server bundle import is safe. The project directory env vars (CLAUDE_PROJECT_DIR, CONTEXT_MODE_PROJECT_DIR) are already set from originalCwd before this point, so server behavior is unaffected.

@bTimor

bTimor commented Jul 9, 2026

Copy link
Copy Markdown

Hey @mattst88! 👋 Thanks for tracking this down — the diagnosis is correct, the fix placement is right, and the ESM-resolution reasoning is sound.

Two things needed before we can merge:

Required: wrap the restore in try/catch

// Before:
process.chdir(originalCwd);

// After:
try { process.chdir(originalCwd); } catch { /* best effort — restore cwd for VTE tab inheritance */ }

Without this, if originalCwd no longer exists at startup time (network FS, container, temp dir cleaned up), the server crashes on launch — which is strictly worse than the original wrong-tab issue. Every other potentially-failing op in start.mjs follows the try { } catch {} defensive pattern; this should too.

Recommended: add a Vitest test

The VITEST guard pattern in start.mjs (if (!process.env.VITEST)) already exists to make the startup sequence testable. A minimal test verifying that process.cwd() after the setup phase equals the pre-launch directory would prevent this from silently regressing. See tests/server-stdin-eof-exit.test.ts for the pattern.

The fix logic is solid — just these two changes and this is good to go. Thanks again!

Restore process.cwd() to the pre-launch directory after chdir(__dirname)
so VTE-based terminals (gnome-terminal) open new tabs in the project
directory rather than the plugin cache directory.

Wrap the restore in try/catch so a missing or unmounted directory (network
FS, container, cleaned-up temp dir) doesn't crash the server on launch.

Add static-analysis tests pinning the restore ordering and defensive
try/catch invariants.

Fixes: mksglu#923
@mattst88
mattst88 force-pushed the fix-start-mjs-chdir branch from 5907fc2 to f4511ac Compare July 9, 2026 15:56
@mattst88

mattst88 commented Jul 9, 2026

Copy link
Copy Markdown
Author

Done, thanks!

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.

start.mjs: process.chdir(__dirname) changes MCP subprocess CWD, breaking gnome-terminal new-tab directory

2 participants