(sidebar): end a dropped session's running state when main drops it (#375) - #402
Conversation
The pty-gone purge ran only when the running-set signature changed, and the status bar count was only redrawn by loadProjects(). A busy signal landing after a poll removed the id left the row busy, and the bar kept counting it. process-exited now removes the id from the running set, drops the activity state through dropLocalPtySession and refreshes the indicators at once; a change of the running set redraws the status bar. Closes #375
|
Reviewing |
|
Adversarial review at |
An exit landing while the same id is being reopened may belong to the old pty, so the drop is skipped until openTerminal answers. The remote guard reads the sidebar row, like the pty-gone scan, and the dead typeof guard on clearActiveSubagentsFor is removed. Refs #375
|
Reviewing |
|
Re-review at |
The opening flag skipped a genuine fast-failing exit and let a stale exit that arrived after the reply through. Main now numbers every spawn, returns the number in the open-terminal reply and sends it with process-exited; the renderer ignores an exit older than the last reply and buffers one that lands during the await until the reply says which pty it belonged to. Refs #375
|
Reviewing |
|
Re-review at |
# Conflicts: # CHANGELOG.md # main.js # test/running-indicators.test.js
Closes #375
What changed
When main drops a local session (
process-exited), the renderer now ends its running state there instead of waiting for the next poll:onProcessExited(public/app.js) removes the id fromactivePtyIds, drops its activity state through the newdropLocalPtySession(live subagents, thenpurgeActivityFor; skipped for remote rows), and runsupdateRunningIndicators()at once.dropLocalPtySession(public/session-activity.js) is the single drop; the existingpty-gonescan inupdateRunningIndicators()uses it too.updateRunningIndicators()callsrenderDefaultStatus()whenever the running set changed. Before, the status bar'sN runningwas only redrawn byloadProjects(), so with no transcript write (CLI stuck in an API retry loop) it stayed stale.Why
The
pty-gonepurge only runs when the running-set signature changes. A busy/notification signal that lands after a poll already removed the id re-armscli-busyon a row the gate never revisits. Fix is at the drop path, not a filter on the count in the view. Rationale is in.ai/contexts/session-state.md("A session main drops").Testing
New
test/dropped-session-state.test.js(the shippedonProcessExitedandupdateRunningIndicatorsare cut out ofapp.jsand run against stubs, as inprocess-exit-status.test.js; the drop helper runs against the realsession-activity.js/sidebar.jsthroughdom-setup.js). All 5 behaviours were red before the change (dropLocalPtySession is not a function, running set still holdingb, status bar not redrawn), green after.Mutations, each turning the new file red then restored: remove
activePtyIds.delete(sessionId)in the exit handler (2 fail); removerenderDefaultStatus()(2 fail); skipdropLocalPtySessionin the exit handler (1 fail); makedropLocalPtySessionskip the purge (2 fail).Existing pins updated for the renamed call:
running-indicators.test.js,session-activity.test.js;process-exit-status.test.jsgets two stubs.eslint.config.jsdeclares the new global.Not verified
The issue was seen once and is not reproduced on demand. The mechanism (a late busy signal after the signature-gated purge, plus the status bar only redrawn by
loadProjects()) is reasoned from the code, not observed live. Not run against a live Electron instance.CHANGELOG: one
### Fixedline under Unreleased.