You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(acp): Session persistence, connection health and UI polish (#45)
* feat(acp): Add heartbeat, dead connection cleanup and connection logging
- Add Rust-side heartbeat task with 15s ping interval and 3-strike disconnect
- Clean up dead connections in `acp_connect` and `acp_check_health`
- Emit structured connection log events via `acp:log`
- Add `HeartbeatEvent`, `ConnectionLogEntry` and `ConnectionConfig` types
- Add `chat_panel_size` field to session persistence
* feat(acp): Persist session state across minimize/restore and reload history
- Add in-memory session cache with global event listener independent of React lifecycle
- Keep DirectoryWorkspace mounted via CSS hidden when minimized
- Add `persistedWorkspaceId` to AppContext for mount/visibility separation
- Always call `acp_load_session` to replay full conversation from ACP backend
- Restore cached messages on "already loaded" fallback
- Add periodic 30s heartbeat in `useAcpConnection` for proactive disconnect detection
- Remove auto-disconnect on unmount; move disconnect to explicit close/forget
- Add connection logs panel with `useAcpLogs` hook and `ConnectionLogs` component
- Add i18n strings for connection logs and ACP status
* test(acp): Add tests for connection hook and logs hook
- Test connect/disconnect lifecycle, status events, workspace isolation
- Test cached state restoration and health check on mount
- Verify disconnect is not called on unmount
- Test log capture, filtering and clear behavior
* style(ui): Replace X icon with Trash2 on session delete button
* fix(acp): Reset session init on disconnect and auto-reload on "not found"
- Reset `initRef` when `isConnected` goes false so reconnect triggers
`doInit` and reloads the session in the new copilot process
- Auto-recover in `sendPrompt`: on "Session not found" (-32602), try
`acp_load_session` then retry the prompt before surfacing the error
* fix(acp): Add 60s streaming timeout to auto-clear stale Stop button
If no streaming event arrives within 60s, `isStreaming` is reset to
false automatically. Prevents the Stop button from staying red
indefinitely when `end_turn` is never received.
* fix: replace native button with shadcn Button and localize aria-label in ErrorConsole
- Use Button (variant=ghost, size=icon) from shadcn/ui
- Add useTranslation() and use t('common.dismiss') for aria-label
- Add common.dismiss key to pt-BR.json ("Dispensar") and en.json ("Dismiss")
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(acp): Avoid awaiting async ops while holding connections mutex
In `acp_connect` and `acp_check_health`, `is_alive().await` and
`shutdown().await` were called while the connections mutex was held,
potentially stalling other ACP commands behind long waits.
Refactored both functions to remove the entry under the lock, drop the
lock, perform async checks/shutdown outside it, then re-acquire the
lock only to re-insert (if still alive) or finalize cleanup.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(acp): Ensure `onConnect` runs even if `onDisconnect` rejects
In `handleReconnect`, if `onDisconnect()` rejected the promise chain
would abort before calling `onConnect()`, leaving the UI stuck in an
error state. Wrapped `onDisconnect` in try/catch so `onConnect`
always executes regardless of disconnect errors.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(acp): Fix listener guard and add streaming timer in session-cache
Flip listenerSetup flag only after the Tauri event listener resolves,
allowing retries if setup fails. Also call resetStreamingTimer() in
addUserMessage so the isStreaming flag is always auto-cleared if no
backend events follow.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(ui): Replace hardcoded hex colors with HSL CSS variables in index.css
Add --terminal-code CSS variable and replace all #3dd68c and #56d4dd
hex values with hsl(var(--success)) and hsl(var(--terminal-code))
respectively, ensuring colors respect the app theme system.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(ui): Use semantic token and localize done label in TerminalMessage
Replace hex color class with text-success/60 semantic token and
localize the hardcoded "done" label via useTranslation().
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(acp): Full state reset on session load and clear idle timer on workspace change
Reset all local state fields (currentMode, availableModes,
activeAcpSessionId, agentPlanFilePath) when loading an existing session
to prevent stale UI state. Also clear idleTimerRef in the workspaceId
effect cleanup so timers don't fire on the wrong workspace.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(ui): Use @/ alias for ConnectionLogs and re-trigger init on session change
Replace relative import with @/ path alias. Add a dedicated effect to
reset initRef when session identity changes so doInit() reruns when a
different session is mounted on the same connected workspace.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(acp): Avoid holding connections mutex during shutdown in acp_disconnect
Drop the connections lock before calling conn.shutdown().await,
consistent with the same fix applied to acp_connect and acp_check_health.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
0 commit comments