Skip to content

fix: always confirm quitting while a task is running - #2112

Closed
Douglasymlai wants to merge 7 commits into
mainfrom
fix/quit-confirmation-running-tasks
Closed

Douglasymlai wants to merge 7 commits into
mainfrom
fix/quit-confirmation-running-tasks

Conversation

@Douglasymlai

@Douglasymlai Douglasymlai commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Pull Request

Related Issue

N/A — maintainer-directed repair; no linked issue required for this PR.

Description

Quit could bypass confirmation when the renderer was unavailable, and loaded-Session checks missed work in other Spaces. Every native quit path now uses the coordinator; unavailable, crashed or silent renderers fall back to a native dialog backed by one 2.5-second global Brain lookup. Unknown state requires confirmation. The registry excludes bare pending Runs and includes attempts/admission claims. Legacy activity checks inspect all loaded tasks. Session deletion retains its separate scoped guard.

Quit skips confirmation entirely when the Brain process is not running, because no task or stream can be running without it. This covers a fresh install and a Brain that failed to start, which previously showed the "couldn't check" dialog on every quit. Admission claims count only when they belong to the live execution service, so a task setup interrupted by an earlier quit or crash no longer makes every later quit report running work.

Quitting while a tool waits for approval is no longer recorded as a rejection. Shutdown cancels the running task before the approval wait is released, and the tool step used to treat that cancellation as a failed tool, which rejected the approval and ended the task with an error. While the app is shutting down, a tool that has not started is now left open, so restart recovery records the task as interrupted by a restart (brain_restart) and the approval card reads "Approval cancelled — Eigent restarted while this task was running". Resume context no longer shows a system-closed approval as a rejected decision, so the agent sees a restart rather than a refusal. Stopping a task or reaching its time limit still closes the tool at once. Clean quit stops terminal resources while keeping environment copies so Resume can reuse them.

The shared confirmation dialog, used by the quit prompt and other confirmations such as deleting or renaming, now uses the Radix dialog like the rest of the app, with the same layout and motion. Escape and a press outside cancel, focus starts on Cancel (or on a field that asks for it) and stays inside the dialog, and closing returns focus to where it was.

Testing Evidence (REQUIRED)

50 frontend tests and 95 backend tests passed (1 backend skip), including unavailable/silent renderer decisions, malformed/unreachable registry, pending admission, cross-Space work, Session deletion compatibility and real approval shutdown followed by restart reconciliation. Type-check, focused ESLint/Prettier, Ruff, locale parity/source checks, Electron access guard and git diff --check passed.

Follow-up commits: 45 frontend tests (the four quit-guard suites) and 31 backend tests (close guard, run controller, approval runtime) passed. They cover quitting with no Brain process from the renderer-ready, renderer-unavailable, native window close and silent-renderer paths, plus a claim left by a killed process after restart. The new coordinator tests fail with the guard removed. Type-check, ESLint, Prettier, Ruff, Electron access guard and git diff --check passed.

Second follow-up commits: a new test drives the real async tool path through a quit at an approval, a restart and the Resume context, for both a quit and an ordinary cancel; it fails with either backend fix removed. New dialog tests cover Escape, a press outside, initial focus, focus return and a field that asks for focus; the Escape and focus tests fail against the old dialog. 457 backend tests passed (1 skip) across permission policy, close guard, Resume context, agent tool execution, run runtime and Resume controllers. Every frontend suite that renders the shared dialog or the quit guard passed, except two UserMenu tests that fail the same way on main. Type-check, ESLint, Prettier, Ruff, the design-token check and git diff --check passed.

Native Electron boundary check passed using unchanged production coordinator/guard sources: unavailable renderer plus active work shows localized confirmation; unknown registry fails closed; Cancel keeps the app open; idle proceeds without a dialog. Localized quit messages are reused and the native dialog uses platform geometry. No new design exception or locale key.

Manual run of the earlier head (macOS dev build): the running-work dialog with Cancel, work in another Space, Interrupted and Resume after a quit, the couldn't-check dialog with a stopped backend, quitting with no backend running, the native fallback after a renderer crash or hang (one alert, not a stack), and translated native alert text behaved as expected. That run found the two issues fixed above; re-running the quit-at-approval and Escape cases on the current head is pending. No packaged build, Windows or Linux run.

  • I have included human-verified testing evidence in this PR.
  • This PR includes frontend/UI changes, and I attached screenshot(s) or screen recording(s).
  • No frontend/UI changes in this PR.

What is the purpose of this pull request?

  • Bug fix
  • New Feature
  • Documentation update
  • Other

Contribution Guidelines Acknowledgement

@Douglasymlai
Douglasymlai marked this pull request as ready for review October 25, 2026 17:53
@Douglasymlai Douglasymlai self-assigned this Oct 25, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

Claude Code Review is paused for this repository because its GitHub organization is not linked to your Claude organization.

To turn it back on, one person needs both roles: owner of the GitHub organization (or the account owner, for a personal repository) and admin or owner of your Claude organization. If that is not you, pass this on to someone who is.

Open Organization settings, Git providers and click Link next to the GitHub organization's name. If it is not listed, click Enable GitHub integration or Connect your GitHub first, whichever the page shows.

New pull requests are then reviewed as before. To get a review on one that is already open, someone with write access can comment @claude review.

Tip: disable this comment in your organization's Code Review settings.

@Douglasymlai

Copy link
Copy Markdown
Contributor Author

Merged into #2111, which now carries these changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant