{"title":"Stovetop, A Home For My Claude Code Sessions","html_url":"https://deallocatedobjects.com/posts/stovetop-a-home-for-my-claude-code-sessions","source_url":"","markdown_content":"I've been working on a Mac app called Stovetop. The tagline is \"Let Claude cook.\"\n\nIt's for anyone who bounces between a lot of Claude Code sessions. On a normal day I'll have a dozen or more going across a few projects: one babysitting a long database job, one working through a feature, a couple running something on a loop, and a pile of older ones I want to come back to later. A regular terminal with a stack of tabs stops working pretty quickly at that size. You lose track of which tab is waiting on you, a reboot or a crash takes everything down with it, and every idle session keeps holding memory.\n\nStovetop is a native Mac app built for exactly that. Each session gets a tab in a sidebar, tabs live in groups, and the app keeps track of what every session is doing so you don't have to.\n\n![The Stovetop settings window, with the Appearance pane open and a theme menu listing Catppuccin, Dracula, Gruvbox, Nord, Rosé Pine, Solarized, Tokyo Night and others. The sidebar has sections for Stovetop, Claude Code and Extensions.](/media/posts/stovetop-a-home-for-my-claude-code-sessions/settings.jpg \"Settings covers the terminal itself plus Claude Code's own config: permissions, model and effort, memory, hooks, MCP servers and skills.\")\n\n### Sessions That Outlive The App\n\nThe part I cared about most is that closing Stovetop shouldn't end anything. Every session runs inside [dtach](https://github.com/crigler/dtach), a tiny program that does one job: it keeps a process alive behind a Unix socket so you can detach from it and attach again later. Stovetop keeps one socket per tab in `~/.stovetop/sessions/`.\n\nWhen `dtach -A` runs, you end up with two processes. The master runs detached, owns the socket, and is the parent of the shell and of Claude Code itself. The attach process is the thing connected to the terminal view, forwarding input and output. The master is the one that has to survive. The attach process is disposable, and the app makes a fresh one whenever it draws a tab again.\n\nSo when Stovetop quits, crashes or updates, the sessions keep working. On the next launch it checks every tab's socket in parallel (that matters once you have 100+ tabs) and reattaches the ones that are still alive. If a socket is gone, say after a reboot, the tab still remembers its Claude session id and starts a fresh session with `--resume`, so the conversation comes right back.\n\nThere was one fun detail here. When you reattach to a running session, Claude Code's interface doesn't redraw by itself, so you get a blank screen until something changes. The fix is to nudge the terminal size: shrink it by a few pixels, then put it back a moment later. That sends a `SIGWINCH` through dtach, and Claude Code repaints. Stovetop does that a few times over the first couple of seconds, so it works even when the attach is slow.\n\nClosing a tab for real tears down the whole tree. Stovetop finds the dtach master for that socket, walks every descendant process (the shell, Claude Code and any MCP servers it started) and stops them from the deepest child up, so nothing gets left running in the background.\n\n### Knowing Which Session Needs You\n\nClaude Code sets the terminal title as it works. When it's idle the title starts with a little asterisk-style glyph, and while it's busy it shows a different glyph and a verb like \"Reading…\" or \"Editing…\". Stovetop parses that title for every tab, so the sidebar can show which sessions are idle, which are working, and which are stuck waiting on a permission prompt or a plan review.\n\nSessions waiting on me also show up as a badge on the Dock icon. I can let ten sessions cook, go do something else, and come back when the badge says somebody needs an answer.\n\nThe title is also where Claude Code puts the name it gives a session, so tab names update themselves. And there's a status bar under every terminal with the model, cost, how full the context is and the git branch, plus buttons for compact, clear and plan mode.\n\n### Pausing What You're Not Using\n\nEvery running session costs memory, and most of mine sit idle for hours. Stovetop can pause a session, which detaches it and frees the terminal, and resume it later right where it left off. You can do it by hand (there's a \"Pause All Other Sessions\" item I use a lot) or turn on auto-pause, which pauses any tab you haven't typed into or looked at for a set amount of time, from 30 minutes up to 8 hours.\n\n### Scheduled Sessions\n\nThe other thing I wanted was a home for recurring work. Stovetop can run scheduled sessions: pick a folder, a prompt and an interval (every 30 minutes, every hour, a few times a day or daily) and it opens a new tab with that prompt when it's due. It's a nice fit for the checks I'd otherwise run by hand every morning.\n\n![The New Tab sheet in Stovetop, with a New Session and Resume toggle, an initial prompt field, and advanced options for the session name, model, permission mode and effort level.](/media/posts/stovetop-a-home-for-my-claude-code-sessions/new-tab.jpg \"New tabs can start fresh or resume an existing session, with a starting prompt and per-session options.\")\n\n### The Terminal Itself\n\nFor the terminal view I'm using GhosttyKit, the library build of [Ghostty](https://ghostty.org). It handles the PTY, Metal rendering, input, scrollback and selection, and Stovetop hands it an `NSView` and forwards events. It brings Ghostty's whole theme collection along with it.\n\nGetting it to play nicely inside SwiftUI took some care. Mouse coordinates are in points, not pixels. Trackpad scrolls need a precision flag or they scroll like a clicky mouse wheel. Pastes and file drops go through a separate text API so they get bracketed paste markers. Control key combos have to skip AppKit's text handling, or Control-A turns into \"move to beginning of line\" before the terminal ever sees it.\n\n### Talking To The Sessions\n\nStovetop also runs a small local MCP server, so a Claude Code session can work with Stovetop itself. It can list tabs and groups, open a new tab in a folder with a starting prompt, rename tabs, move them between groups, send input to another tab and open a URL. That lets one session hand work off to a fresh one, or tidy up my sidebar for me.\n\n### Lots Of Little Things\n\nThere's a long tail of smaller features I use every day. Quick Open (Command-K) jumps to any tab or recent folder. Back and forward work like a browser, across tabs. Closed tabs come back with Command-Shift-T. Groups can nest. There's per-tab environment variables, templates for sessions I start often, tags, archiving, on-device voice input with Whisper, transcript search across every session, and a session summarizer that can write a summary, release notes or a commit message for a tab, a group or everything since the last commit.\n\nIt's built with SwiftUI, GRDB for the SQLite database and XcodeGen for the project. Stovetop isn't out yet. I'm using it all day, every day, and I'll share more as it gets closer.","html_content":"<p>I’ve been working on a Mac app called Stovetop. The tagline is “Let Claude cook.”</p>\n<p>It’s for anyone who bounces between a lot of Claude Code sessions. On a normal day I’ll have a dozen or more going across a few projects: one babysitting a long database job, one working through a feature, a couple running something on a loop, and a pile of older ones I want to come back to later. A regular terminal with a stack of tabs stops working pretty quickly at that size. You lose track of which tab is waiting on you, a reboot or a crash takes everything down with it, and every idle session keeps holding memory.</p>\n<p>Stovetop is a native Mac app built for exactly that. Each session gets a tab in a sidebar, tabs live in groups, and the app keeps track of what every session is doing so you don’t have to.</p>\n<p><figure class=\"image\"><img src=\"https://deallocatedobjects.com/media/posts/stovetop-a-home-for-my-claude-code-sessions/settings.jpg\" alt=\"The Stovetop settings window, with the Appearance pane open and a theme menu listing Catppuccin, Dracula, Gruvbox, Nord, Rosé Pine, Solarized, Tokyo Night and others. The sidebar has sections for Stovetop, Claude Code and Extensions.\" loading=\"lazy\" decoding=\"async\" width=\"1012\" height=\"852\"><figcaption>Settings covers the terminal itself plus Claude Code’s own config: permissions, model and effort, memory, hooks, MCP servers and skills.</figcaption></figure></p>\n<h2 id=\"sessions-that-outlive-the-app\" data-level=\"3\">Sessions That Outlive The App</h2>\n<p>The part I cared about most is that closing Stovetop shouldn’t end anything. Every session runs inside <a href=\"https://github.com/crigler/dtach\">dtach</a>, a tiny program that does one job: it keeps a process alive behind a Unix socket so you can detach from it and attach again later. Stovetop keeps one socket per tab in <code>~/.stovetop/sessions/</code>.</p>\n<p>When <code>dtach -A</code> runs, you end up with two processes. The master runs detached, owns the socket, and is the parent of the shell and of Claude Code itself. The attach process is the thing connected to the terminal view, forwarding input and output. The master is the one that has to survive. The attach process is disposable, and the app makes a fresh one whenever it draws a tab again.</p>\n<p>So when Stovetop quits, crashes or updates, the sessions keep working. On the next launch it checks every tab’s socket in parallel (that matters once you have 100+ tabs) and reattaches the ones that are still alive. If a socket is gone, say after a reboot, the tab still remembers its Claude session id and starts a fresh session with <code>--resume</code>, so the conversation comes right back.</p>\n<p>There was one fun detail here. When you reattach to a running session, Claude Code’s interface doesn’t redraw by itself, so you get a blank screen until something changes. The fix is to nudge the terminal size: shrink it by a few pixels, then put it back a moment later. That sends a <code>SIGWINCH</code> through dtach, and Claude Code repaints. Stovetop does that a few times over the first couple of seconds, so it works even when the attach is slow.</p>\n<p>Closing a tab for real tears down the whole tree. Stovetop finds the dtach master for that socket, walks every descendant process (the shell, Claude Code and any MCP servers it started) and stops them from the deepest child up, so nothing gets left running in the background.</p>\n<h2 id=\"knowing-which-session-needs-you\" data-level=\"3\">Knowing Which Session Needs You</h2>\n<p>Claude Code sets the terminal title as it works. When it’s idle the title starts with a little asterisk-style glyph, and while it’s busy it shows a different glyph and a verb like “Reading…” or “Editing…”. Stovetop parses that title for every tab, so the sidebar can show which sessions are idle, which are working, and which are stuck waiting on a permission prompt or a plan review.</p>\n<p>Sessions waiting on me also show up as a badge on the Dock icon. I can let ten sessions cook, go do something else, and come back when the badge says somebody needs an answer.</p>\n<p>The title is also where Claude Code puts the name it gives a session, so tab names update themselves. And there’s a status bar under every terminal with the model, cost, how full the context is and the git branch, plus buttons for compact, clear and plan mode.</p>\n<h2 id=\"pausing-what-youre-not-using\" data-level=\"3\">Pausing What You’re Not Using</h2>\n<p>Every running session costs memory, and most of mine sit idle for hours. Stovetop can pause a session, which detaches it and frees the terminal, and resume it later right where it left off. You can do it by hand (there’s a “Pause All Other Sessions” item I use a lot) or turn on auto-pause, which pauses any tab you haven’t typed into or looked at for a set amount of time, from 30 minutes up to 8 hours.</p>\n<h2 id=\"scheduled-sessions\" data-level=\"3\">Scheduled Sessions</h2>\n<p>The other thing I wanted was a home for recurring work. Stovetop can run scheduled sessions: pick a folder, a prompt and an interval (every 30 minutes, every hour, a few times a day or daily) and it opens a new tab with that prompt when it’s due. It’s a nice fit for the checks I’d otherwise run by hand every morning.</p>\n<p><figure class=\"image\"><img src=\"https://deallocatedobjects.com/media/posts/stovetop-a-home-for-my-claude-code-sessions/new-tab.jpg\" alt=\"The New Tab sheet in Stovetop, with a New Session and Resume toggle, an initial prompt field, and advanced options for the session name, model, permission mode and effort level.\" loading=\"lazy\" decoding=\"async\" width=\"553\" height=\"774\"><figcaption>New tabs can start fresh or resume an existing session, with a starting prompt and per-session options.</figcaption></figure></p>\n<h2 id=\"the-terminal-itself\" data-level=\"3\">The Terminal Itself</h2>\n<p>For the terminal view I’m using GhosttyKit, the library build of <a href=\"https://ghostty.org\">Ghostty</a>. It handles the PTY, Metal rendering, input, scrollback and selection, and Stovetop hands it an <code>NSView</code> and forwards events. It brings Ghostty’s whole theme collection along with it.</p>\n<p>Getting it to play nicely inside SwiftUI took some care. Mouse coordinates are in points, not pixels. Trackpad scrolls need a precision flag or they scroll like a clicky mouse wheel. Pastes and file drops go through a separate text API so they get bracketed paste markers. Control key combos have to skip AppKit’s text handling, or Control-A turns into “move to beginning of line” before the terminal ever sees it.</p>\n<h2 id=\"talking-to-the-sessions\" data-level=\"3\">Talking To The Sessions</h2>\n<p>Stovetop also runs a small local MCP server, so a Claude Code session can work with Stovetop itself. It can list tabs and groups, open a new tab in a folder with a starting prompt, rename tabs, move them between groups, send input to another tab and open a URL. That lets one session hand work off to a fresh one, or tidy up my sidebar for me.</p>\n<h2 id=\"lots-of-little-things\" data-level=\"3\">Lots Of Little Things</h2>\n<p>There’s a long tail of smaller features I use every day. Quick Open (Command-K) jumps to any tab or recent folder. Back and forward work like a browser, across tabs. Closed tabs come back with Command-Shift-T. Groups can nest. There’s per-tab environment variables, templates for sessions I start often, tags, archiving, on-device voice input with Whisper, transcript search across every session, and a session summarizer that can write a summary, release notes or a commit message for a tab, a group or everything since the last commit.</p>\n<p>It’s built with SwiftUI, GRDB for the SQLite database and XcodeGen for the project. Stovetop isn’t out yet. I’m using it all day, every day, and I’ll share more as it gets closer.</p>","created_at":"2026-04-01T13:00:00.000Z","updated_at":"2026-04-01T13:00:00.000Z"}