@@ -25,7 +25,7 @@ use crate::{
2525 session_manager::{
2626 GLOBAL_DIR_NAME, INSTANCE_FILENAME, VM_MANAGER_PID_NAME, VM_MANAGER_SOCKET_NAME,
2727 },
28− vm::{self, DirectoryShare, LoginAction, VmInput},
28+ vm::{self, DirectoryShare, LoginAction, PROJECT_GUEST_BASE, VmInput},
2929};
3030
3131const VM_MANAGER_LOCK_NAME: &str = "vm.lock";
@@ -200,6 +200,30 @@ fn cleanup_stale_manager(instance_dir: &Path) {
200200 let _ = fs::remove_file(&pid_path);
201201}
202202
203+fn inject_project_mount(
204+ mounts: &mut Vec<String>,
205+ project_root: &Path,
206+ ssh_user: &str,
207+ project_name: &str,
208+) {
209+ let guest_tilde = format!("~/{project_name}");
210+ let guest_home = format!("/home/{ssh_user}/{project_name}");
211+ let guest_base = format!("{PROJECT_GUEST_BASE}/{project_name}");
212+ let already_mapped = mounts.iter().any(|spec| {
213+ let parts: Vec<&str> = spec.split(':').collect();
214+ if parts.len() < 2 {
215+ return false;
216+ }
217+ let guest = parts[1];
218+ guest == guest_tilde || guest == guest_home || guest == guest_base
219+ });
220+ if already_mapped {
221+ return;
222+ }
223+ let host = project_root.display();
224+ mounts.insert(0, format!("{host}:{guest_tilde}:read-write"));
225+}
226+
203227fn is_socket_path(path: &Path) -> bool {
204228 fs::metadata(path)
205229 .map(|meta| meta.file_type().is_socket())
@@ -252,7 +276,7 @@ fn rewrite_mount_spec(spec: &str, ssh_user: &str) -> (String, Option<HomeLink>)
252276 return (spec.to_string(), None);
253277 }
254278
255− let root_base = "/usr/local/vibebox-mounts";
279+ let root_base = PROJECT_GUEST_BASE;
256280 let root_path = if rel.is_empty() {
257281 root_base.to_string()
258282 } else {
@@ -563,7 +587,7 @@ impl VmExecutor for RealVmExecutor {
563587
564588fn run_manager_with(
565589 project_root: &Path,
566− args: vm::VmArg,
590+ mut args: vm::VmArg,
567591 auto_shutdown_ms: u64,
568592 executor: &dyn VmExecutor,
569593 options: ManagerOptions,
@@ -602,8 +626,12 @@ fn run_manager_with(
602626 .lock()
603627 .map(|cfg| cfg.ssh_user_display())
604628 .unwrap_or_else(|_| DEFAULT_SSH_USER.to_string());
629+ if !args.no_default_mounts {
630+ inject_project_mount(&mut args.mounts, project_root, &ssh_user, &project_name);
631+ }
605632 let (args, home_links_script) = prepare_mounts_and_links(args, &ssh_user);
606633
634+ let project_guest_dir = format!("{PROJECT_GUEST_BASE}/{project_name}");
607635 let ssh_guest_dir = format!("/root/{}", GLOBAL_DIR_NAME);
608636 let extra_shares = vec![DirectoryShare::new(
609637 instance_dir.clone(),
@@ -613,6 +641,7 @@ fn run_manager_with(
613641 let extra_login_actions = build_ssh_login_actions(
614642 &config,
615643 &project_name,
644+ &project_guest_dir,
616645 ssh_guest_dir.as_str(),
617646 "ssh_key",
618647 &home_links_script,