- Add SessionOperationsContext + SessionProgressPanel for global, non-blocking lifecycle progress (create/start/stop/restart/delete/ recreate-tunnel) driven by SSE events. - Promote SessionsContext to authoritative shared session state with refresh, addOrUpdateSession, and removeSession helpers. - Wire AppShell, DashboardPage, SessionsPage, useInstanceActions, ToolStarter, and InstanceList into shared state so lists update immediately after create/delete without manual refresh. - Remove legacy blocking overlays from CreateSessionForm, SessionCard, and InstanceList; keep disabled states and inline spinners only. - Update DashboardPage tests to wrap with SessionsProvider and SessionOperationsProvider. - Add .cache/ to .gitignore. Quality gates: npm run typecheck, npm run lint, npm test -- --run (82 passed).
3.9 KiB
Design: Tool Session Progress and Live Updates
Goals / Non-Goals
Goals:
- Provide structured, real-time progress feedback for every tool lifecycle action.
- Ensure all session lists (nav, dashboard, sessions page) update immediately after create/delete.
- Remove blocking and card-dimming overlays that hide context and provide no step detail.
- Keep the change frontend-only, reusing existing SSE and session APIs.
Non-Goals:
- No new backend endpoints or event types.
- No changes to the actual Docker/container orchestration logic.
- No redesign of the session card layout beyond action/progress affordances.
Decisions
Decision: Global progress panel in the corner
A fixed panel (bottom-right desktop, bottom sheet style on mobile) lists in-flight operations. Each operation shows:
- Action icon + session display name
- Current step label derived from the latest SSE event
- A compact stepper: Created → Building → Starting → Probing → Ready/Error
- Dismiss button once settled
This is non-blocking, works across pages, and does not interfere with the modal create flow.
Decision: SSE event-driven updates
The panel subscribes to useEvents. When an operation is started we record instanceId + action. Incoming events that match a tracked instance update the operation's message, status, and step. Events handled:
instance.created,instance.started,instance.restarted→ advanceinstance.health_changedwithstatus=running→ complete successinstance.error→ complete errorinstance.stopped→ complete for stop actioninstance.deleted→ complete for delete action
Decision: Shared session state
SessionsContext is promoted from a nav-only data holder to the authoritative session list:
- Holds
sessions,isLoading,error,refreshSessions(). - Provides
addOrUpdateSession,removeSessionfor optimistic updates. AppShell,DashboardPage, andSessionsPageread from this context instead of fetching independently.
Decision: Optimistic create/delete updates
- Create: after the API returns a pending instance, add it to shared state and start tracking. Subsequent SSE events update its status.
- Delete: remove from shared state as soon as the API succeeds; the progress panel tracks the action until the
instance.deletedevent confirms it. - Other actions: keep the existing per-action busy flag on the card for button disabled states, but the panel provides the detailed progress.
Decision: Remove legacy overlays
- Delete
loading-overlayand workflow step markup fromCreateSessionForm. - Remove
session-busy-overlayandinstance-busy-overlay(the dimming overlays), but keep button disabled states and small inline spinners.
Risks / Trade-offs
Risk: Shared context causes extra re-renders → Mitigation: context value is memoized; lists use the same data they already fetched.
Risk: SSE events arriving before operation is tracked → Mitigation: start tracking before calling the create/start API; for deletes the removal is optimistic and the panel reconciles on the event.
Risk: Duplicate feedback between panel and toasts
→ Mitigation: panel shows in-flight steps; toasts remain for terminal success/error only. Existing EventToastBridge logic is left largely unchanged.
Migration Plan
- Extend
SessionsContextwith loading/error/refresh/update helpers. - Create
SessionOperationsContext+SessionProgressPaneland render it inAppShell. - Update
useInstanceActionsto use shared state and start/stop tracking operations. - Update
ToolStarter/StartToolFABto add pending sessions and start tracking. - Update
CreateSessionFormto remove overlay and report status to parent. - Update
InstanceListto refresh shared state after create/delete. - Update
SessionsPageandDashboardPageto consume shared context. - Remove legacy overlay styles.
- Run typecheck, lint, and tests.