fix: resolve double-nested home paths in cowork mountPath (#373)

The mountPath() methods in HostBackend, BwrapBackend, and KvmBackend
joined os.homedir() with a root-relative subpath, causing paths like
/home/user/home/user/.config/Claude/... instead of the correct
/home/user/.config/Claude/...

The subpath parameter is encoded as path.relative("/", absolutePath),
making it root-relative. Joining with "/" instead of os.homedir()
produces the correct absolute path.

Fixes #373

Co-Authored-By: Claude <claude@anthropic.com>

https://claude.ai/code/session_01TEWYXVLaKgBfKVkHY47g9M
This commit is contained in:
Claude
2026-04-03 12:33:33 +00:00
parent 0782c5a70e
commit 0bcc245c95
2 changed files with 43 additions and 3 deletions

View File

@@ -731,7 +731,7 @@ class HostBackend extends LocalBackend {
async mountPath(params) {
const { subpath } = params;
log(`HostBackend mountPath: ${subpath}`);
const guestPath = path.join(os.homedir(), subpath || '');
const guestPath = path.join('/', subpath || '');
return { guestPath };
}
}
@@ -910,7 +910,7 @@ class BwrapBackend extends LocalBackend {
async mountPath(params) {
const { subpath, mountName } = params;
log(`BwrapBackend mountPath: ${mountName} -> ${subpath}`);
const hostPath = path.join(os.homedir(), subpath || '');
const hostPath = path.join('/', subpath || '');
// Store for --bind on next spawn
this.mountBinds.set(mountName || subpath, hostPath);
return { guestPath: hostPath };
@@ -1720,7 +1720,7 @@ class KvmBackend extends BackendBase {
}
// No home share — return host path with a warning
const hostPath = path.join(os.homedir(), subpath || '');
const hostPath = path.join('/', subpath || '');
log('KvmBackend: no home share, returning host path');
return { guestPath: hostPath };
}

View File

@@ -823,3 +823,43 @@ assertEqual(
"
[[ "$status" -eq 0 ]]
}
# =============================================================================
# mountPath — subpath is root-relative, must NOT be joined with homedir
# =============================================================================
# These tests replicate the mountPath() logic from HostBackend and
# BwrapBackend to verify that root-relative subpaths resolve correctly
# (fix for #373: double-nested home directory paths).
@test "mountPath: root-relative subpath resolves to absolute path, not double-nested" {
run node -e "${NODE_PREAMBLE}
// Simulate what the caller sends: path.relative('/', '/home/user/.config/Claude')
const subpath = 'home/user/.config/Claude';
// Fixed logic: join with '/' (root), not os.homedir()
const guestPath = path.join('/', subpath);
assertEqual(guestPath, '/home/user/.config/Claude',
'root-relative subpath should resolve to single absolute path');
"
[[ "$status" -eq 0 ]]
}
@test "mountPath: empty subpath resolves to root" {
run node -e "${NODE_PREAMBLE}
const guestPath = path.join('/', '');
assertEqual(guestPath, '/', 'empty subpath -> root');
"
[[ "$status" -eq 0 ]]
}
@test "mountPath: subpath with nested directories resolves correctly" {
run node -e "${NODE_PREAMBLE}
const subpath = 'home/raycharlizard/.config/Claude/local-agent-mode-sessions/outputs';
const guestPath = path.join('/', subpath);
assertEqual(guestPath,
'/home/raycharlizard/.config/Claude/local-agent-mode-sessions/outputs',
'nested subpath should not double the home prefix');
"
[[ "$status" -eq 0 ]]
}