29a12bb102
- Add expand_container_path() helper that resolves ~/ and $HOME/ prefixes
- Add get_manifest_home_dir() to compute /home/{user.name} or /root from manifest
- Set ENV HOME=... and ENV USER=... in generated Dockerfile for runtime compatibility
- Pass home_dir through instance creation and startup pipeline
- Expand mount targets in apply_resolved_profile() for regular profile mounts
- Expand mapping targets in _resolve_git_mount_mappings() for git mounts
- Expand working_directory and volume targets in _modify_compose_file()
- Update _prepare_manifest_instance to return home_dir alongside image tag
- Fetch tool_type early in start_instance to determine home_dir before profile application
Quality gates: pytest 188 passed, frontend typecheck clean
Addresses: home-path-expansion
3.6 KiB
3.6 KiB
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.fileskeys): 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$HOMEwith/rootin 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.namefrom manifest, compute home as/home/{name}or/root - For legacy tools: default to
/root - Pass
home_dirthrough 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_directoryfield 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
apps/api/src/services/config_profile_resolver.py— addexpand_container_path()helperapps/api/src/api/tool_instances.py— passhome_dirtoapply_resolved_profile()and git mount functions; determine home from manifest/tool typeapps/api/src/services/manifest_compiler.py— expose helper to extract user from manifest- 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 |