Commit Graph

6 Commits

Author SHA1 Message Date
Alex Blank c6b804bf0a feat: fix SSH key mounting with multi-key support and unique filenames
SSH key mounting was broken because:
1. Each selected key was mounted to a separate source dir but all targeted
   the same ~/.ssh path in the container, causing Docker Compose's
   last-mount-wins behavior
2. All keys were named id_ed25519, so they'd overwrite each other

Changes:
- ssh_keys.py: add key_filename param to prepare_ssh_key_files for unique
  key names; add write_ssh_config for combined multi-key config
- tool_instances.py: collect all selected keys into a single ~/.ssh mount
  with sanitized unique filenames (id_ed25519_<name>); generate combined
  SSH config with all IdentityFile entries
- tests: add os.makedirs mock for SSH permission tests

Quality gates: pytest (19 passed, 1 skipped)
2026-06-02 15:03:26 +02:00
Alex Blank 906aab3b73 fix: workspace creation with stale directories and missing bind mount
- workspace_manager.py: remove stale workspace directories before cloning
  to prevent 'already exists' errors from previous failed attempts
- workspaces.py: add ValueError -> 400 handling, keep 409 for duplicates
- test_tool_instances_legacy.py: fix broken patches for new helpers
  (get_container_name removed, _ensure_backend_network_in_compose added,
  workspace_id/ssh_key_ids mock attributes added)
- docker-compose.traefik.yml: add /data/working-copies bind mount

Quality gates: pytest (19 passed, 1 skipped)
2026-06-02 13:41:07 +02:00
Alex Blank 03d22c4d06 fix: set SSH key ownership to container user with mode 600
- Mount SSH keys as bind (not ro) so docker exec --user root can chown
- Add apply_ssh_permissions() to permission_fixer.py
- Call apply_ssh_permissions() after container start for all instance types
- Derive container user from home_dir (/root → root, /home/user → user)
- Tests: apply_ssh_permissions unit tests + start_instance integration tests

Quality gates: pytest 236 passed (6 pre-existing failures), tsc --noEmit clean
2026-05-29 14:04:52 +02:00
Alex Blank 8926152fca fix: unified fullscreen terminal header
- Add showControls prop to TerminalComponent to optionally hide internal header
- Add reset() method to TerminalRef for external reset control
- TerminalPage now renders a unified fullscreen header bar combining:
  - Session tabs (TerminalSessionTabs)
  - Terminal controls (status dot, A-, A+, Reset, Exit Fullscreen)
- Unified header is always visible in fullscreen (no hover-to-reveal)
- TerminalComponent internal header hidden when in fullscreen mode
- Remove old CSS that hid session tabs with opacity:0 until hover

Quality gates: pytest 188 passed, frontend typecheck clean

Fixes: terminal-fullscreen-unified-header
2026-05-29 10:34:31 +02:00
Alex Blank 29a12bb102 feat: expand ~ and $HOME in mount target paths
- 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
2026-05-29 00:01:04 +02:00
Alex Blank 3e99e7f197 feat: legacy fallback tests and docs (PR 3)
- Add test_tool_instances_legacy.py with 8 unit tests:
  - dockerfile definition type builds from template
  - dockerfile build failure raises HTTP 500
  - compose definition type renders template
  - manifest compiler is NOT called for legacy types
  - start_instance legacy/compose/dockerfile types all skip manifest flow
  - start_instance manifest type correctly invokes compiler
- Mark T3.2 and T3.3 tasks complete in OpenSpec
- Add openspec/docs/tool-workshop-guide.md with user guide covering
  definition types, manifest creation workflow, base definitions,
  migration path, and permissions
2026-05-28 14:54:32 +02:00