Repository navigation
feat: sleep a session to free its resources - #212
Open
kaminskypavel wants to merge 2 commits into
Open
kaminskypavel wants to merge 2 commits into
kaminskypavel wants to merge 2 commits into
Conversation
`z`, or Sleep in a live card's right-click menu, ends the agent's process (the CLI and the MCP servers it started) and keeps its card. Attaching it again resumes the conversation, as after an idle reap. The idle reaper never takes a session in the worktree being viewed, so this is the way to free one of those. It always asks first. A working agent (running, waiting on the user, or with a backgrounded tool call still going) is refused, by the TUI and again by the daemon on the reaper's own test. Cold, archived and cloud cards have nothing to sleep and say so. New request SleepAgent (protocol 52), only sent to a daemon that speaks it.
Contributor
|
hmm I think maybe there is a bug with the idle reaper as well. it should sleep any session that hasn't had activity based on the idle timeout setting. I'll have to look into this, but thanks for the PR, I will merge after I research. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
zon an idle session asks firstA session can now be put to sleep:
z(or Sleep in a live card's right-click menu) ends its agent process to free the memory and CPU it holds, and keeps the card where it is. The IDLE REAPER never takes a session in the worktree you are viewing, so with six sessions onmainnone of them was ever freed short of archiving; Sleep frees them without losing the card.Contents
✨ What you get
🧹 Free a session without archiving it
z, or Sleep in the card's right-click menusleepin Settings › HotkeysEnter, a click, or resting the cursor on itsession_idle_timeoutare untouched; Sleep is the manual version of what the reaper already does🛡️ Never cut a turn short
dandauseEnter/ysleeps,Esc/nkeeps it running'name' is still working; sleep it once it is idle🧭 How it flows
sequenceDiagram actor U as User participant T as TUI participant D as DAEMON participant C as agent CLI U->>T: z on a card alt Running / NeedsFeedback, cold, archived or cloud T-->>U: footer says why, nothing sent else idle and live T->>U: Sleep agent? confirm U->>T: Enter / y T->>T: release the pane if it shows the card T->>D: SleepAgent { id } alt busy (status or detached job) D-->>T: Error "still working" else idle D->>C: kill_session D-->>T: EntityUpserted (alive: false) end end U->>T: later: attach the card T->>D: Attach D->>C: respawn with resume🎯 Attack surface
ClientRequest::SleepAgent. Reached only by a client already connected to the DAEMON's 0700 socket, the same callers asArchiveAgentandDeleteAgent, which already kill the same process. Held by: the existing socket auth; the request only kills a session nebula itself spawned and keeps the row. Not held: nothing new; it is strictly weaker thanDeleteAgent.Verdict: 🟢 Low risk: one additive request that reuses the archive and reaper kill path, refuses busy agents, and touches no hot path.
kill_sessionthe reaper, Archive and Delete already calldetached_job_under, run on a cloned session outside the lockMenuAction,PendingAction, CONFIRM DIALOG, keymap entry, protocol-gated request likeCheckWorktreeRollback:
git revertremoves the key, the menu row and the request. PROTOCOL VERSION goes back to 51; a TUI built from this branch then refuses to send Sleep to that daemon (it is gated), so nothing breaks either way.🔧 Technical overview
Daemon::sleep_agentreads the row, refuses an archived one and a busy one (Running/NeedsFeedback, oragent_has_detached_jobon the live PTY, the IDLE REAPER's test), thenkill_sessionandbroadcast_agent, so every client seesalive: false. Waking is the existing reaped-session path: the nextAttachboots the CLI with its resume flag. The TUI checks the same conditions first for a precise footer, opens the confirm, and on Enter detaches the pane if it shows the card (so nothing re-attaches it straight back), then sends the request.crates/nebula-daemon/src/registry/lifecycle.rs:sleep_agent;crates/nebula-daemon/src/server.rs: the request handler;crates/nebula-core/src/protocol.rs:SleepAgent, PROTOCOL VERSION 52,SLEEP_AGENT_PROTOCOL;crates/nebula-tui/src/event_loop/actions.rs:sleep_agent,sleep_agent_now,confirm_sleep_agent, the menu row;crates/nebula-tui/src/keymap.rs:z;docs/keys.md: the key's row.dalready closes one.cargo fmt --checkclean,cargo clippy --workspace --all-targetsclean,cargo test -p nebula-core -p nebula-daemon -p nebula-tui --lib1,795 passed,cargo test -p nebula(e2e) 121 passed. New tests:sleep_kills_an_idle_process_and_keeps_the_row(daemon, real PTY) andz_asks_then_sleeps_an_idle_card_and_refuses_a_running_one(TUI).branch_switch::tests::stash_and_switch_leaves_the_changes_in_a_named_stashfailed once in a full parallel run and passes alone and with--test-threads=4; it does not touch this code.📝 Notes
upstream/mainat5c361c7(v0.46.0 + 2); no conflicts.MIN_COMPATIBLE_PROTOCOLstays 49): an older DAEMON keeps working with this TUI, andzthere says to restart the daemon.nebula reloadmoves a running daemon onto the new binary with its sessions.make shot SCENE=sleep-confirmandSCENE=sleep-after.🤖 Generated with Claude Code