- Add null checks and try/catch around fitAddon.fit() to prevent viewport errors
- Use requestAnimationFrame to ensure DOM is stable before fitting
- Remove isMobile condition from font size buttons in TerminalComponent
- Font size controls now visible on both mobile and desktop terminals
- Add safety check after rendering compose template to ensure REPO_PATH is mounted
- If compose template lacks volume mount, auto-add default mount to /workspace
- Add cloned repo verification to catch empty clone directories
Refs: clone mode repo not appearing in container workspace
- TerminalComponent: expose changeFontSize via onTerminalReady callback
- MobileTerminalWrapper: pass changeFontSize to header
- MobileTerminalHeader: add A- and A+ font size buttons
- CSS: collapse header height/padding/margin/border when hidden to reclaim space
Backend:
- Add created_at to get_user_sessions response
Frontend:
- Hide tunnel error badges, probe output, and 'Recreate Tunnel' button for terminal-only sessions
- Show session start time (created_at) in active sessions list
- Show repository configuration (clone_mode, branch) for each session
- Skip health check polling for terminal-only sessions
- Update Session type to include created_at field
- Create merge migration f3d2dc90ba3a to merge single_interface and clone_mode heads
- Make remove_is_builtin migration idempotent with IF EXISTS clause
Refs: alembic migration fix for dev branch
- Remove useSpecialKeys hook state, export pure utility functions instead
- MobileTerminalWrapper now owns activeModifier state
- SpecialKeysStrip and SpecialKeysPanel receive modifier via props
- TerminalComponent applies modifier to virtual keyboard input via activeModifier prop
- Modifier now works with both special keys AND virtual keyboard input
- Modifier clears after any key press (special or virtual keyboard)
- Redesign useSpecialKeys hook with modifier state tracking
- Add one-shot activation for Ctrl and Alt keys
- Visual feedback: active modifiers shown with yellow highlight
- Fix focusInput to use term.focus() instead of hidden input
- Always refocus terminal after sending any special key
- Add requestAnimationFrame for reliable focus restoration
Git branch -a --format=%(refname:short) returns remote branches as
'origin/branch-name', not 'remotes/origin/branch-name'. The code was
only filtering 'remotes/' prefix, causing clone to fail with branch
names like 'origin/feat/foo'.
Now properly detects remote names using 'git remote' and strips the
remote prefix (e.g., 'origin/') from branch names.
- Add tabIndex={-1} to all special key buttons to prevent focus
- Add onFocus handler to immediately blur if focused
- Terminal focus stays intact when tapping special keys
- Move terminal hidden input to off-screen position (-9999px) to prevent
text selection/caret visibility on mobile
- Add user-select: none to prevent any selection UI
- Fix create-session-form to use new listRepositoryBranches API signature
(projectId, repoId) and access response.branches/default_branch
Resolved conflicts:
- Moved branch selection UI from inline sessions.tsx to CreateSessionForm component
- Integrated branch dropdown and new branch creation into CreateSessionForm
- Removed duplicate branch state management from sessions.tsx
All branch selection tests pass (7/7).
- Use onPointerDown with preventDefault() instead of onClick
- Add onKeepFocus callback to SpecialKeysStrip and SpecialKeysPanel
- Expose focusInput via onTerminalReady in TerminalComponent
- MobileTerminalWrapper passes focus callback to keep keyboard open
- Remove status from TerminalComponent useEffect dependencies to prevent recreation on WebSocket status changes
- Use ref for onTerminalReady callback to avoid parent re-renders triggering terminal recreation
- Wrap MobileTerminalWrapper onTerminalReady with useCallback for stable reference
- Replace free-text branch input with dropdown of available branches
- Add 'Create new branch...' option with name and base branch inputs
- Load branches from API when repository is selected in clone mode
- Pass newBranch parameter to createInstance API
- Add new_branch field to CreateInstanceRequest
- Run git checkout -b after cloning when new_branch is provided
- Store new branch name in ToolInstance record
- Drop is_builtin column from tool_types table
- Remove built-in tool seeding from startup
- Remove is_builtin from API schemas and frontend types
- Update tool-types spec to reflect removal of built-in concept
- Add Alembic migration for column removal
- Update tests to work without built-in distinction
Move the loading overlay from the active sessions section to the create
session section so it dims the form itself during creation, providing
better visual feedback to the user.
The loading overlay for instance creation was inside the active sessions
grid, which doesn't render when there are no active sessions. Moved the
overlay to the parent container so it's always visible during creation
regardless of existing sessions.
Add loading overlay to sessions list during create, stop, delete,
and recreate tunnel operations. Show progress messages like
'Creating instance...' and 'Starting container...' during creation.
Dim the sessions grid while operations are in progress to prevent
user confusion and accidental duplicate actions.
Remove 500-character truncation on probe output so users can see
all attempts including the final successful one. Add probe status
indicator (passed/failed/pending) that's always visible when probe
data exists.
The backend was returning 'tool_type_interface_type' (string) but the
frontend expected 'tool_type_interfaces' (array). This caused
undefined.includes() crash when clicking Open on terminal sessions.
Changed both list_instances and get_user_sessions to return
tool_type_interfaces as an array. Also added clone_mode and branch
to get_user_sessions response.
For terminal-only tools like OpenCode, default_port is 0 which is falsy
in Python. The code incorrectly treated port 0 as 'not configured' and
marked the instance as error. Now we only check if tool_type exists,
and default to port 0. Terminal tools skip tunnel creation anyway.
For terminal-only tools (no URL), only check container status for
overall health instead of requiring tunnel health. Terminal tools
do not have tunnels, so tunnel_status stays as 'not_applicable'
which was failing the healthy check.