{"repo":"NousResearch/hermes-agent","public_id":"43744","display_label":"Desktop folder picker broken for WSL/remote gateway","summary":"Reports and fixes around the desktop folder picker showing incorrect Windows paths or local filesystem paths when using WSL backends or remote gateway connections. Includes related work on a remote-gateway-aware picker and git tooling.","subsystem":"apps/desktop","counts":{"members":4,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":2,"merged_prs":1,"attempt_prs":1},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":63105},"resolution":{"state":"partially_resolved","by":"pr-63105"},"freshness":{"state":"verified","last_verified_at":"2026-07-13T03:17:50+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_PARTIAL","link_density":0.3933333333333333},"fix_edges":[{"issue_number":43744,"pr_number":63105,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true}],"members":[{"kind":"issue","number":43744,"title":"Hermes Desktop: Change working directory picker only shows Windows paths (WSL backend)","url":null,"state":"closed"},{"kind":"issue","number":52946,"title":"[Bug]: Desktop project folder picker shows local filesystem when connected to remote gateway","url":null,"state":"closed"},{"kind":"pr","number":43809,"title":"fix(desktop): bridge Windows folder picker paths for WSL backends","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#63105","number":63105}],"category":"superseded_by_pr","implication":"superseded"},"merged":false},{"kind":"pr","number":63105,"title":"fix(desktop): bridge Windows folder-picker paths for WSL backends (supersedes #43809)","url":null,"state":"merged","close_reason":{"category":"merged","implication":"superseded"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["acp_adapter/session.py","apps/desktop/electron/fs-read-dir.ts","apps/desktop/electron/main.ts","apps/desktop/electron/wsl-path-bridge.test.ts","apps/desktop/electron/wsl-path-bridge.ts","apps/desktop/package.json","hermes_constants.py","scripts/release.py","tests/test_hermes_constants.py","tui_gateway/server.py"],"fix_hunks":[{"file":"acp_adapter/session.py","hunks":["@@ -26,31 +26,18 @@\n logger = logging.getLogger(__name__)\n \n \n-def _win_path_to_wsl(path: str) -> str | None:\n-    \"\"\"Convert a Windows drive path to its WSL /mnt/<drive>/... equivalent.\"\"\"\n-    match = re.match(r\"^([A-Za-z]):[\\\\/](.*)$\", path)\n-    if not match:\n-        return None\n-    drive = match.group(1).lower()\n-    tail = match.group(2).replace(\"\\\\\", \"/\")\n-    return f\"/mnt/{drive}/{tail}\"\n-\n-\n def _translate_acp_cwd(cwd: str) -> str:\n     \"\"\"Translate Windows ACP cwd values when Hermes itself is running in WSL.\n \n     Windows ACP clients can launch ``hermes acp`` inside WSL while still sending\n-    editor workspaces as Windows drive paths such as ``E:\\\\Projects``. Store\n-    and execute against the WSL mount path so agents, tools, and persisted ACP\n-    sessions all agree on the usable workspace. Native Linux/macOS keeps the\n-    original cwd unchanged.\n+    editor workspaces as Windows drive paths (``E:\\\\Projects``) or\n+    ``\\\\\\\\wsl.localhost\\\\`` UNC paths. Store and execute against the POSIX form so\n+    agents, tools, and persisted ACP sessions all agree on the usable workspace.\n+    Native Linux/macOS keeps the original cwd unchanged.\n     \"\"\"\n-    from hermes_constants import is_wsl\n+    from hermes_constants import translate_cwd_for_wsl_backend\n \n-    if not is_wsl():\n-        return cwd\n-    translated = _win_path_to_wsl(str(cwd))\n-    return translated if translated is not None else cwd\n+    return translate_cwd_for_wsl_backend(str(cwd))\n \n \n def _normalize_cwd_for_compare(cwd: str | None) -> str:","@@ -61,7 +48,9 @@ def _normalize_cwd_for_compare(cwd: str | None) -> str:\n \n     # Normalize Windows drive paths into the equivalent WSL mount form so\n     # ACP history filters match the same workspace across Windows and WSL.\n-    translated = _win_path_to_wsl(expanded)\n+    from hermes_constants import windows_path_to_wsl\n+\n+    translated = windows_path_to_wsl(expanded)\n     if translated is not None:\n         expanded = translated\n     elif re.match(r\"^/mnt/[A-Za-z]/\", expanded):"]},{"file":"apps/desktop/electron/fs-read-dir.ts","hunks":["@@ -2,6 +2,7 @@ import fs from 'node:fs'\n import path from 'node:path'\n \n import { resolveDirectoryForIpc } from './hardening'\n+import { resolveLocalReadPath } from './wsl-path-bridge'\n \n const FS_READDIR_STAT_CONCURRENCY = 16\n ","@@ -81,8 +82,12 @@ async function readDirForIpc(dirPath, options: any = {}) {\n   const fsImpl = options.fs || fs\n   let resolved\n \n+  // On a Windows host with a WSL backend, a WSL/POSIX cwd (`/home/...`,\n+  // `/mnt/c/...`) isn't readable as-is; bridge it to a UNC/drive form first.\n+  const readPath = resolveLocalReadPath(String(dirPath ?? ''))\n+\n   try {\n-    ;({ resolvedPath: resolved } = await resolveDirectoryForIpc(dirPath, {\n+    ;({ resolvedPath: resolved } = await resolveDirectoryForIpc(readPath, {\n       fs: fsImpl,\n       purpose: 'Directory read'\n     }))"]},{"file":"apps/desktop/electron/main.ts","hunks":["@@ -65,6 +65,7 @@ import {\n } from './desktop-uninstall'\n import { installEmbedReferer } from './embed-referer'\n import { readDirForIpc } from './fs-read-dir'\n+import { resolvePickerDefaultPath } from './wsl-path-bridge'\n import { probeGatewayWebSocket } from './gateway-ws-probe'\n import { scanGitRepos } from './git-repo-scan'\n import {","@@ -8037,7 +8038,10 @@ ipcMain.handle('hermes:selectPaths', async (_event, options: any = {}) => {\n \n   if (options?.defaultPath) {\n     try {\n-      resolvedDefaultPath = path.resolve(String(options.defaultPath))\n+      // On a Windows host with a WSL backend the cwd may be a POSIX/WSL path;\n+      // bridge it to a UNC/drive form the native dialog can actually open.\n+      const bridged = IS_WINDOWS ? resolvePickerDefaultPath(String(options.defaultPath)) : String(options.defaultPath)\n+      resolvedDefaultPath = bridged ? path.resolve(bridged) : undefined\n     } catch {\n       resolvedDefaultPath = undefined\n     }"]},{"file":"apps/desktop/electron/wsl-path-bridge.test.ts","hunks":["@@ -0,0 +1,40 @@\n+import assert from 'node:assert/strict'\n+import test from 'node:test'\n+\n+import { parseDefaultDistro, resolvePickerDefaultPath, wslPosixToWindowsAccessible } from './wsl-path-bridge'\n+\n+test('parseDefaultDistro reads the first distro from clean utf-8 output', () => {\n+  assert.equal(parseDefaultDistro('Ubuntu\\nDebian\\n'), 'Ubuntu')\n+})\n+\n+test('parseDefaultDistro survives UTF-16LE NUL bytes older wsl.exe leaves in (WSL#4607)', () => {\n+  // `wsl.exe -l -q` emits UTF-16LE without a BOM on builds that ignore\n+  // WSL_UTF8; decoded as utf8 that reads as NUL-interleaved text.\n+  const utf16ish = '\\0U\\0b\\0u\\0n\\0t\\0u\\0\\r\\0\\n\\0D\\0e\\0b\\0i\\0a\\0n\\0'\n+  assert.equal(parseDefaultDistro(utf16ish), 'Ubuntu')\n+})\n+\n+test('parseDefaultDistro strips the default-marker and blank lines', () => {\n+  assert.equal(parseDefaultDistro('\\n* Ubuntu\\nDebian\\n'), 'Ubuntu')\n+  assert.equal(parseDefaultDistro('   \\n\\n'), null)\n+})\n+\n+test('wslPosixToWindowsAccessible maps a drvfs mount to its Windows drive', () => {\n+  assert.equal(wslPosixToWindowsAccessible('/mnt/c/Users/alex', 'Ubuntu'), 'C:\\\\Users\\\\alex')\n+  assert.equal(wslPosixToWindowsAccessible('/mnt/d', 'Ubuntu'), 'D:\\\\')\n+})\n+\n+test('wslPosixToWindowsAccessible maps an in-distro POSIX path to a UNC share', () => {\n+  assert.equal(wslPosixToWindowsAccessible('/home/alex/proj', 'Ubuntu'), '\\\\\\\\wsl.localhost\\\\Ubuntu\\\\home\\\\alex\\\\proj')\n+})\n+\n+test('wslPosixToWindowsAccessible leaves non-absolute / already-Windows paths alone', () => {\n+  assert.equal(wslPosixToWindowsAccessible('C:\\\\Users\\\\alex', 'Ubuntu'), 'C:\\\\Users\\\\alex')\n+  assert.equal(wslPosixToWindowsAccessible('relative/dir', 'Ubuntu'), 'relative/dir')\n+})\n+\n+test('resolvePickerDefaultPath bridges a WSL cwd but passes Windows paths and empties through', () => {\n+  assert.equal(resolvePickerDefaultPath('/home/alex', 'Ubuntu'), '\\\\\\\\wsl.localhost\\\\Ubuntu\\\\home\\\\alex')\n+  assert.equal(resolvePickerDefaultPath('C:\\\\proj', 'Ubuntu'), 'C:\\\\proj')\n+  assert.equal(resolvePickerDefaultPath(undefined, 'Ubuntu'), undefined)\n+})"]},{"file":"apps/desktop/electron/wsl-path-bridge.ts","hunks":["@@ -0,0 +1,136 @@\n+import { execFileSync } from 'node:child_process'\n+import fs from 'node:fs'\n+\n+// Bridges WSL/POSIX paths into forms the *Windows host* can open, for the case\n+// where the desktop UI runs on Windows and the gateway runs inside WSL (remote\n+// mode). Only the Windows-side direction lives here: the native folder dialog's\n+// defaultPath and the fs read path. The reverse (whatever path the backend\n+// receives → POSIX) is handled once, gateway-side, in\n+// hermes_constants.translate_cwd_for_wsl_backend, so it stays picker-agnostic.\n+\n+const IS_WINDOWS = process.platform === 'win32'\n+const WIN_DRIVE_RE = /^([A-Za-z]):[\\\\/]/\n+// `/mnt/c` and `/mnt/c/...` (drvfs default automount root).\n+const WSL_MOUNT_RE = /^\\/mnt\\/([a-z])(?:\\/(.*))?$/i\n+\n+let cachedDistro: null | string = null\n+let cachedUncBase: null | string = null\n+\n+/**\n+ * Pick the default distro from `wsl.exe -l -q` output.\n+ *\n+ * `wsl.exe` emits UTF-16LE without a BOM unless `WSL_UTF8=1` (WSL >= 0.64), so\n+ * older builds leave NUL bytes between characters even when we ask for utf8 —\n+ * strip them defensively before splitting. The default distro is the first\n+ * (`*`-marked, decoration removed by `-q`) entry. See microsoft/WSL#4607.\n+ */\n+export function parseDefaultDistro(raw: string): null | string {\n+  return (\n+    String(raw || '')\n+      .replace(/\\0/g, '')\n+      .split(/\\r?\\n/)\n+      .map(line => line.replace(/^\\*?\\s*/, '').trim())\n+      .find(Boolean) || null\n+  )\n+}\n+\n+/** Default WSL distro name (cached). Falls back to `Ubuntu`. */\n+export function resolveDefaultWslDistro(): string {\n+  if (cachedDistro) {\n+    return cachedDistro\n+  }\n+\n+  if (!IS_WINDOWS) {\n+    cachedDistro = 'Ubuntu'\n+\n+    return cachedDistro\n+  }\n+\n+  try {\n+    const out = execFileSync('wsl.exe', ['-l', '-q'], {\n+      encoding: 'utf8',\n+      env: { ...process.env, WSL_UTF8: '1' },\n+      timeout: 2000,\n+      windowsHide: true\n+    })\n+    cachedDistro = parseDefaultDistro(out) || 'Ubuntu'\n+  } catch {\n+    cachedDistro = 'Ubuntu'\n+  }\n+\n+  return cachedDistro\n+}\n+\n+// `\\\\wsl.localhost\\<distro>` (Win11 / Win10 >= 21364) with a `\\\\wsl$\\<distro>`\n+// fallback for older builds. Probed once; defaults to wsl.localhost.\n+function wslUncBase(distro: string): string {\n+  if (cachedUncBase) {\n+    return cachedUncBase\n+  }\n+\n+  const modern = `\\\\\\\\wsl.localhost\\\\${distro}`\n+  const legacy = `\\\\\\\\wsl$\\\\${distro}`\n+\n+  try {\n+    if (!fs.existsSync(modern) && fs.existsSync(legacy)) {\n+      cachedUncBase = legacy\n+\n+      return cachedUncBase\n+    }\n+  } catch {\n+    // Network-path probe failed — prefer the modern form.\n+  }\n+\n+  cachedUncBase = modern\n+\n+  return cachedUncBase\n+}\n+\n+/**\n+ * A WSL/POSIX path → a path the Windows host can open: `/mnt/c/...` → `C:\\...`\n+ * (drvfs mount), any other absolute POSIX path → `\\\\wsl.localhost\\<distro>\\...`.\n+ * Non-absolute or already-Windows paths pass through.\n+ */\n+export function wslPosixToWindowsAccessible(posixPath: string, distro: string = resolveDefaultWslDistro()): string {\n+  const value = String(posixPath || '').trim()\n+  const normalized = value.replace(/\\\\/g, '/')\n+\n+  if (!normalized.startsWith('/')) {\n+    return value\n+  }\n+\n+  const mount = normalized.match(WSL_MOUNT_RE)\n+\n+  if (mount) {\n+    const tail = (mount[2] || '').replace(/\\//g, '\\\\')\n+\n+    return tail ? `${mount[1].toUpperCase()}:\\\\${tail}` : `${mount[1].toUpperCase()}:\\\\`\n+  }\n+\n+  const relative = normalized.replace(/^\\/+/, '').replace(/\\//g, '\\\\')\n+\n+  return `${wslUncBase(distro)}\\\\${relative}`\n+}\n+\n+/** Native folder dialog `defaultPath`: open a WSL cwd in the Windows picker. */\n+export function resolvePickerDefaultPath(\n+  defaultPath: string | undefined,\n+  distro: string = resolveDefaultWslDistro()\n+): string | undefined {\n+  if (!defaultPath) {\n+    return undefined\n+  }\n+\n+  const value = String(defaultPath).trim()\n+\n+  return value.startsWith('/') && !WIN_DRIVE_RE.test(value) ? wslPosixToWindowsAccessible(value, distro) : defaultPath\n+}\n+\n+/** fs read path: on Windows, make a WSL cwd readable via its UNC / drive form. */\n+export function resolveLocalReadPath(dirPath: string, distro: string = resolveDefaultWslDistro()): string {\n+  const value = String(dirPath || '').trim()\n+\n+  return IS_WINDOWS && value.startsWith('/') && !WIN_DRIVE_RE.test(value)\n+    ? wslPosixToWindowsAccessible(value, distro)\n+    : value\n+}"]},{"file":"apps/desktop/package.json","hunks":["@@ -38,7 +38,7 @@\n     \"test:desktop:nsis\": \"node scripts/test-desktop.mjs nsis\",\n     \"test:desktop:existing\": \"node scripts/test-desktop.mjs existing\",\n     \"test:desktop:fresh\": \"node scripts/test-desktop.mjs fresh\",\n-    \"test:desktop:platforms\": \"node --test electron/bootstrap-platform.test.ts electron/hardening.test.ts electron/backend-env.test.ts electron/backend-probes.test.ts electron/backend-ready.test.ts electron/bootstrap-runner.test.ts electron/connection-config.test.ts electron/dashboard-token.test.ts electron/gateway-ws-probe.test.ts electron/oauth-net-request.test.ts electron/desktop-uninstall.test.ts electron/session-windows.test.ts electron/link-title-window.test.ts electron/workspace-cwd.test.ts electron/fs-read-dir.test.ts electron/git-root.test.ts electron/git-worktree-ops.test.ts electron/windows-child-process.test.ts electron/update-remote.test.ts electron/update-count.test.ts electron/update-rebuild.test.ts electron/update-marker.test.ts electron/update-relaunch.test.ts electron/windows-user-env.test.ts electron/wsl-clipboard-image.test.ts electron/titlebar-overlay-width.test.ts electron/window-state.test.ts electron/zoom.test.ts electron/windows-hermes-resolution.test.ts electron/oauth-session-request.test.ts\",\n+    \"test:desktop:platforms\": \"node --test electron/bootstrap-platform.test.ts electron/hardening.test.ts electron/backend-env.test.ts electron/backend-probes.test.ts electron/backend-ready.test.ts electron/bootstrap-runner.test.ts electron/connection-config.test.ts electron/dashboard-token.test.ts electron/gateway-ws-probe.test.ts electron/oauth-net-request.test.ts electron/desktop-uninstall.test.ts electron/session-windows.test.ts electron/link-title-window.test.ts electron/workspace-cwd.test.ts electron/fs-read-dir.test.ts electron/wsl-path-bridge.test.ts electron/git-root.test.ts electron/git-worktree-ops.test.ts electron/windows-child-process.test.ts electron/update-remote.test.ts electron/update-count.test.ts electron/update-rebuild.test.ts electron/update-marker.test.ts electron/update-relaunch.test.ts electron/windows-user-env.test.ts electron/wsl-clipboard-image.test.ts electron/titlebar-overlay-width.test.ts electron/window-state.test.ts electron/zoom.test.ts electron/windows-hermes-resolution.test.ts electron/oauth-session-request.test.ts\",\n     \"typecheck\": \"tsc -p . --noEmit && tsc -p tsconfig.electron.json --noEmit\",\n     \"lint\": \"eslint src/ electron/\",\n     \"lint:fix\": \"eslint src/ electron/ --fix\","]},{"file":"hermes_constants.py","hunks":["@@ -854,6 +854,48 @@ def is_wsl() -> bool:\n     return _wsl_detected\n \n \n+def windows_path_to_wsl(path: str) -> str | None:\n+    \"\"\"Convert a Windows drive path (``C:\\\\...``) to its ``/mnt/<drive>/...`` form.\"\"\"\n+    import re\n+\n+    match = re.match(r\"^([A-Za-z]):[\\\\/](.*)$\", str(path or \"\").strip())\n+    if not match:\n+        return None\n+    drive = match.group(1).lower()\n+    tail = match.group(2).replace(\"\\\\\", \"/\")\n+    return f\"/mnt/{drive}/{tail}\"\n+\n+\n+def wsl_unc_path_to_posix(path: str) -> str | None:\n+    \"\"\"Convert a Windows WSL UNC path (``\\\\\\\\wsl.localhost\\\\<distro>\\\\...`` or the\n+    legacy ``\\\\\\\\wsl$\\\\...``) to a POSIX path inside the distro.\"\"\"\n+    import re\n+\n+    normalized = str(path or \"\").strip().replace(\"/\", \"\\\\\")\n+    match = re.match(r\"^\\\\\\\\wsl(?:\\.localhost|\\$)\\\\[^\\\\]+\\\\(.*)$\", normalized, re.IGNORECASE)\n+    if not match:\n+        return None\n+    tail = match.group(1).replace(\"\\\\\", \"/\")\n+    return f\"/{tail}\" if tail else \"/\"\n+\n+\n+def translate_cwd_for_wsl_backend(cwd: str) -> str:\n+    \"\"\"Normalize a cross-boundary cwd when Hermes itself runs inside WSL.\n+\n+    A Windows-host UI (native picker / drive path / ``\\\\\\\\wsl.localhost\\\\`` UNC)\n+    can hand the WSL backend a path it can't ``chdir`` into. Map it to the POSIX\n+    equivalent so the picker, sidebar, and sessions all agree on the workspace.\n+    No-op off WSL and for paths that are already POSIX.\n+    \"\"\"\n+    if not is_wsl():\n+        return cwd\n+    for translator in (wsl_unc_path_to_posix, windows_path_to_wsl):\n+        translated = translator(cwd)\n+        if translated is not None:\n+            return translated\n+    return cwd\n+\n+\n _container_detected: bool | None = None\n \n "]},{"file":"scripts/release.py","hunks":["@@ -45,6 +45,7 @@\n \n # Auto-extracted from noreply emails + manual overrides\n AUTHOR_MAP = {\n+    \"[redacted:email]\": \"VrtxOmega\",  # PR #43809 salvage (desktop: WSL folder-picker path bridge)\n     \"[redacted:email]\": \"ansel-f\",  # PR #62388 salvage (approval: allow exact verifier temp cleanup without broadening rm safety boundary)\n     \"[redacted:email]\": \"Hopfensaft\",  # PR #31933 salvage (dashboard: align approvals.mode dropdown with canonical engine values)\n     \"[redacted:email]\": \"professorpalmer\",  # PR #48591 salvage (sessions: CLI workspace filter + restore-cwd-on-resume)"]},{"file":"tests/test_hermes_constants.py","hunks":["@@ -834,3 +834,38 @@ def test_symlink_to_empty_dir_returns_new(self, tmp_path, monkeypatch):\n         legacy.symlink_to(empty)\n         result = get_hermes_dir(\"cache/audio\", \"audio_cache\")\n         assert result == tmp_path / \"cache/audio\"\n+\n+\n+class TestWslPathTranslation:\n+    \"\"\"Cross-boundary path translation for a Windows-host UI + WSL backend.\"\"\"\n+\n+    def test_windows_drive_to_wsl_mount(self):\n+        assert hermes_constants.windows_path_to_wsl(r\"C:\\Users\\alex\") == \"/mnt/c/Users/alex\"\n+        assert hermes_constants.windows_path_to_wsl(\"C:/Users/alex\") == \"/mnt/c/Users/alex\"\n+        assert hermes_constants.windows_path_to_wsl(\"D:\\\\\") == \"/mnt/d/\"\n+\n+    def test_windows_drive_ignores_non_drive_paths(self):\n+        assert hermes_constants.windows_path_to_wsl(\"/home/alex\") is None\n+        assert hermes_constants.windows_path_to_wsl(\"relative\\\\dir\") is None\n+\n+    def test_wsl_unc_to_posix_both_spellings(self):\n+        assert hermes_constants.wsl_unc_path_to_posix(r\"\\\\wsl.localhost\\Ubuntu\\home\\alex\") == \"/home/alex\"\n+        assert hermes_constants.wsl_unc_path_to_posix(r\"\\\\wsl$\\Ubuntu\\home\\alex\") == \"/home/alex\"\n+        # Forward-slash spelling and distro root.\n+        assert hermes_constants.wsl_unc_path_to_posix(\"//wsl.localhost/Debian/srv/app\") == \"/srv/app\"\n+        assert hermes_constants.wsl_unc_path_to_posix(\"\\\\\\\\wsl.localhost\\\\Ubuntu\\\\\") == \"/\"\n+\n+    def test_wsl_unc_ignores_non_unc_paths(self):\n+        assert hermes_constants.wsl_unc_path_to_posix(r\"C:\\Users\\alex\") is None\n+        assert hermes_constants.wsl_unc_path_to_posix(\"/home/alex\") is None\n+\n+    def test_translate_is_noop_off_wsl(self, monkeypatch):\n+        monkeypatch.setattr(hermes_constants, \"is_wsl\", lambda: False)\n+        assert hermes_constants.translate_cwd_for_wsl_backend(r\"C:\\Users\\alex\") == r\"C:\\Users\\alex\"\n+\n+    def test_translate_maps_windows_and_unc_on_wsl(self, monkeypatch):\n+        monkeypatch.setattr(hermes_constants, \"is_wsl\", lambda: True)\n+        assert hermes_constants.translate_cwd_for_wsl_backend(r\"C:\\Users\\alex\") == \"/mnt/c/Users/alex\"\n+        assert hermes_constants.translate_cwd_for_wsl_backend(r\"\\\\wsl.localhost\\Ubuntu\\home\\alex\") == \"/home/alex\"\n+        # Already-POSIX paths pass through untouched.\n+        assert hermes_constants.translate_cwd_for_wsl_backend(\"/home/alex\") == \"/home/alex\""]},{"file":"tui_gateway/server.py","hunks":["@@ -1859,7 +1859,10 @@ def _run() -> None:\n \n \n def _set_session_cwd(session: dict, cwd: str) -> str:\n-    resolved = os.path.abspath(os.path.expanduser(str(cwd)))\n+    from hermes_constants import translate_cwd_for_wsl_backend\n+\n+    cwd = translate_cwd_for_wsl_backend(str(cwd))\n+    resolved = os.path.abspath(os.path.expanduser(cwd))\n     if not os.path.isdir(resolved):\n         raise ValueError(f\"working directory does not exist: {cwd}\")\n     session[\"cwd\"] = resolved\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}