fix: Project action terminal lifecycle (#3287)

* fix(terminal): make command sessions own action lifecycle

* fix(ui): reconcile project action terminal state

* feat(ui): show running project actions in terminal tabs

* feat(ui): run project actions from linked worktrees

* fix(ui): guard project action reconciliation

* fix(ui): scope project action preview fallback

* fix(ui): default project actions to worktrees

* fix(ui): reveal project action terminals

* fix(ui): retain terminal output after snapshot replay

* fix(ui): restore running action terminals on revisit
This commit is contained in:
Matt Visnovsky
2026-09-05 12:04:36 +03:00
committed by GitHub
parent 58dfc789a2
commit 4e0eed717d
53 changed files with 5194 additions and 608 deletions
+5
View File
@@ -18,6 +18,7 @@ import { TooltipProvider } from '@/components/ui/tooltip';
import { Toaster } from '@/components/ui/sonner';
import { usePushVisibilityBeacon } from '@/hooks/usePushVisibilityBeacon';
import { useRouter } from '@/hooks/useRouter';
import { useTerminalSessionKeepalive } from '@/hooks/useTerminalSessionKeepalive';
import { useUpdatePolling } from '@/hooks/useUpdatePolling';
import { useWindowTitle } from '@/hooks/useWindowTitle';
import { opencodeClient } from '@/lib/opencode/client';
@@ -105,6 +106,10 @@ type MobileSurface = 'instances' | 'settings' | 'update';
const MobileShell: React.FC<{ onActiveConnectionDeleted: () => void }> = ({ onActiveConnectionDeleted }) => {
const { t } = useI18n();
// The mobile root does not mount MainLayout, so it owns its own terminal
// keepalive: without it, background PTYs (running project actions included)
// are idle-reaped by the server while the workspace drawer is closed.
useTerminalSessionKeepalive();
const [sessionsSheetOpen, setSessionsSheetOpen] = React.useState(false);
const [activeSurface, setActiveSurface] = React.useState<MobileSurface | null>(null);
// Phone right drawer with the workspace tabs; the tab persists across