Skip to content

fix(desktop): honor default project directory for new sessions#43234

Merged
OutThisLife merged 2 commits into
mainfrom
austin/fix/desktop-home-cwd-regression
Jun 10, 2026
Merged

fix(desktop): honor default project directory for new sessions#43234
OutThisLife merged 2 commits into
mainfrom
austin/fix/desktop-home-cwd-regression

Conversation

@austinpickett

@austinpickett austinpickett commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Fixes a regression where Settings → Archived Chats → Default project directory saved correctly in the main process (project-dir.json) but new desktop sessions still started in the user's home directory.

The renderer was seeding $currentCwd from sticky localStorage (hermes.desktop.workspace-cwd, PR #37586) and never preferred the configured default when calling session.create. Restarting the gateway could not help because the cwd was never passed from the picker choice.

This PR wires the configured default through boot, new-chat draft, and session.create; pins TERMINAL_CWD on backend spawn to match resolveHermesCwd(); and rejects packaged install-dir paths (e.g. win-unpacked) that could slip back in via INIT_CWD or remembered workspace paths (PR #37536 item 16 follow-up).

Related Issue

Fixes #

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • apps/desktop/electron/main.cjsisPackagedInstallPath, sanitizeWorkspaceCwd, skip INIT_CWD when packaged, set TERMINAL_CWD on backend spawn, hermes:workspace:sanitize IPC
  • apps/desktop/electron/preload.cjs — expose sanitizeWorkspaceCwd
  • apps/desktop/src/store/session.ts — cache configured default, ensureDefaultWorkspaceCwd, workspaceCwdForNewSession
  • apps/desktop/src/app/gateway/hooks/use-gateway-boot.ts — seed workspace on boot
  • apps/desktop/src/app/session/hooks/use-session-actions.ts — new chats use configured default
  • apps/desktop/src/app/settings/sessions-settings.tsx — apply picker choice to live workspace immediately
  • apps/desktop/src/global.d.ts, apps/desktop/src/i18n/en.ts — bridge/types + clearer success toast

How to Test

  1. Open Settings → Archived ChatsDefault project directory → choose a folder that is not your home directory.
  2. Start a new chat (Ctrl/⌘+N) and send: "What directory are you working in?"
  3. Confirm the agent reports the chosen folder (not home).
  4. Clear the setting → new chat should fall back to home.
  5. (Packaged build) Confirm new sessions do not land in the app install dir (win-unpacked / .app bundle).

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: WSL2 / Linux (manual desktop dev verification pending reviewer)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

N/A — delete section.

Screenshots / Logs

N/A — renderer + Electron IPC change; verify via steps above.

The Settings picker persisted project-dir.json but the renderer kept
seeding new chats from sticky localStorage home. Prefer the configured
default on boot and session.create, pin TERMINAL_CWD at backend spawn,
and reject packaged install-dir paths that regressed after #37536.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

🔎 Lint report: austin/fix/desktop-home-cwd-regression vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 10626 on HEAD, 10626 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 5564 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have labels Jun 10, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review Summary

Verdict: Approved

Looks Good:

  • Fixes desktop app honoring the configured default project directory for new sessions. Previously the Electron preload or main process was not properly passing the configured project directory to session creation, causing new sessions to default to the wrong directory.
  • 8 files, +158/-10. Touches Electron main/preload, React hooks, i18n, and store code.
  • Test added for the config-driven project directory.
  • Clean, well-scoped fix.

Reviewed by Hermes Agent

@OutThisLife OutThisLife left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review

Verdict: Comment (not blocking the design — the root-cause fix is right — but two things should land before merge)

Looks good

  • Correct root cause: the renderer was seeding $currentCwd from sticky localStorage and never preferring the configured default. Wiring it through boot (ensureDefaultWorkspaceCwd), the new-chat draft, and session.create (workspaceCwdForNewSession()) is the right place to fix it.
  • Pinning TERMINAL_CWD: hermesCwd on both backend spawns closes the stale-config-bridge gap so tools don't drift back to the install dir. Good catch.
  • Defense-in-depth in main.cjs is sound: dropping INIT_CWD/process.cwd() when packaged and rejecting install-tree paths via isPackagedInstallPath() directly addresses the #37536 item 16 regression.
  • Nice consistency cleanup making defaultLabel/i18n report home (~) instead of the phantom ~/hermes-projects that resolveHermesCwd() never actually returned.

Should address before merge

1. No test for a bug fix. Per AGENTS.md (tests required for bug fixes), this needs coverage, and the pure logic here is trivially testable — apps/desktop/src/store/session.test.ts already exercises store helpers like mergeSessionPage/sessionPinId, so workspaceCwdForNewSession() (configured > remembered > live precedence) belongs right next to them. isPackagedInstallPath() / sanitizeWorkspaceCwd() are similarly unit-testable. (Note: the automated review above states "Test added for the config-driven project directory" — there is no test file in this diff; the checklist box is also unchecked.)

2. applyConfiguredDefaultProjectDir() mutates the live workspace of the active session. It calls setCurrentCwd(configured) unconditionally, and it runs both on the Settings panel mount (sessions-settings.tsx get-effect) and on pick. If a chat is already active in a different directory, this retargets the displayed $currentCwd (and persists it to localStorage) even though the running session's backend cwd is unchanged — and it contradicts your own new toast, "start a new chat (Ctrl/⌘+N) for it to take effect." Suggest splitting concerns: always update the cached configuredDefaultProjectDir, but only setCurrentCwd(...) when there's no active session (fresh draft). That keeps the cache correct for the next new chat without visually rewriting a live session's cwd.

Otherwise clean and well-scoped.

Add workspace cwd precedence tests, extract isPackagedInstallPath for
platform test coverage, and stop rewriting live $currentCwd when a
session is already active (cache-only until the next new chat).

Co-authored-by: Cursor <cursoragent@cursor.com>
@austinpickett austinpickett requested a review from a team June 10, 2026 04:19
@austinpickett

Copy link
Copy Markdown
Collaborator Author

Addressed the review feedback in a379576:

1. Tests added

  • apps/desktop/src/store/session.test.tsworkspaceCwdForNewSession() precedence (configured > remembered > live) and active-session guard
  • apps/desktop/electron/workspace-cwd.test.cjs — extracted isPackagedInstallPath() pure helper + platform test wiring

2. Active session no longer gets its live cwd rewritten

  • applyConfiguredDefaultProjectDir() and ensureDefaultWorkspaceCwd() now only call setCurrentCwd() when $activeSessionId is empty
  • The configured default is still cached for the next Ctrl/⌘+N, matching the toast copy

Let me know if anything else should change before merge.

@OutThisLife OutThisLife left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-review — both points resolved in a379576f

1. Tests ✅workspaceCwdForNewSession() precedence (configured > remembered > live) + the active-session-guard case in session.test.ts, and isPackagedInstallPath() extracted into a DI'd pure module (workspace-cwd.cjs) with workspace-cwd.test.cjs wired into test:desktop:platforms. Bonus: main.cjs now delegates instead of duplicating the loop, and the helper is testable without Electron.

2. Live cwd no longer clobbered ✅ — both applyConfiguredDefaultProjectDir() and ensureDefaultWorkspaceCwd() gate setCurrentCwd(...) on !$activeSessionId.get() via the seedLiveCwd helper; the cache update stays unconditional so the next new chat still honors the default. Matches the toast's contract.

Clean, well-scoped, and tested. LGTM.

@OutThisLife OutThisLife merged commit 1770263 into main Jun 10, 2026
20 checks passed
@OutThisLife OutThisLife deleted the austin/fix/desktop-home-cwd-regression branch June 10, 2026 04:29
changman pushed a commit to changman/hermes-agent that referenced this pull request Jun 10, 2026
…esearch#43234)

* fix(desktop): honor default project directory for new sessions

The Settings picker persisted project-dir.json but the renderer kept
seeding new chats from sticky localStorage home. Prefer the configured
default on boot and session.create, pin TERMINAL_CWD at backend spawn,
and reject packaged install-dir paths that regressed after NousResearch#37536.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(desktop): address review on default project dir PR

Add workspace cwd precedence tests, extract isPackagedInstallPath for
platform test coverage, and stop rewriting live $currentCwd when a
session is already active (cache-only until the next new chat).

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants