# Exploration: ~ / $HOME Expansion in Mount Paths ## User Request Allow `~` and `$HOME` in mount paths for both regular mounts and git mounts. ## Where This Applies ### Container target paths (where it makes sense) - **Regular mounts** (`mount.target`): The absolute path inside the container where files are bind-mounted - **Git mount mappings** (`mapping.target_path`): The absolute path inside the container where repo subdirectories are mounted ### Where it does NOT apply - **Regular mount file paths** (`mount.files` keys): These are relative to the mount target - **Git mount source paths** (`mapping.source_path`): These are relative to the cloned repo - **Host-side source paths**: The API runs in a container; `~` on the host would mean the Docker host's home, which the API container cannot access ## Complexity Assessment ### The Core Problem `~` means "user's home directory". But whose home? | Context | Home Directory | Knowable at Mount Time? | |---------|---------------|------------------------| | API container | `/root` or `/app` | Yes | | Target container (manifest, user=root) | `/root` | Yes (from manifest) | | Target container (manifest, user=user) | `/home/user` | Yes (from manifest) | | Target container (legacy tool type) | Unknown | No (assume `/root`) | | Docker host | `/home/alex` or similar | No (API is containerized) | ### Docker Compose Reality Check Docker Compose **does not expand** `~` or `$HOME` in volume targets. These are passed literally to the Docker daemon. So `~/workspace` becomes a directory literally named `~` in the container root. This means **we must resolve the path ourselves** before writing the compose file. ## Design Options ### Option A: Simple `/root` default (minimal change) - Replace `~` and `$HOME` with `/root` in all container target paths - Apply during compose modification and git mount resolution - **Effort**: ~30 min, ~20 lines - **Pros**: Dead simple, works for root-running containers (most legacy setups) - **Cons**: Wrong for pi-agent (runs as `user`, home `/home/user`) ### Option B: Manifest-aware home directory (recommended) - For manifest-based tools: read `user.name` from manifest, compute home as `/home/{name}` or `/root` - For legacy tools: default to `/root` - Pass `home_dir` through the mount resolution pipeline - Apply expansion in `apply_resolved_profile()` and `_resolve_git_mount_mappings()` - **Effort**: ~2 hours, touches 3-4 files - **Pros**: Correct for all container types - **Cons**: Slightly more plumbing ### Option C: Configurable home per profile - Add `home_directory` field to ConfigProfile - User can override the container home directory - **Effort**: ~3 hours, schema change - **Cons**: Overkill, clutters UI ## Recommendation **Option B** — manifest-aware expansion. The pi-agent manifest already declares `user.name`, so we can compute the correct home directory. For backward compatibility, legacy tool types default to `/root`. ## Files to Touch 1. `apps/api/src/services/config_profile_resolver.py` — add `expand_container_path()` helper 2. `apps/api/src/api/tool_instances.py` — pass `home_dir` to `apply_resolved_profile()` and git mount functions; determine home from manifest/tool type 3. `apps/api/src/services/manifest_compiler.py` — expose helper to extract user from manifest 4. Tests for expansion logic ## Risks | Risk | Mitigation | |------|------------| | Wrong home for custom containers | Document that manifest should declare `user.name` | | `$HOME` env var not set in container | We resolve it at compose generation time, so no runtime dependency | | Breaking existing profiles with literal `~` in path | Very unlikely; we can add an escape hatch if needed |