BossTerm v1.2.183

3 hours ago

BossTerm 1.2.183 changes a default you will notice. The session daemon, the background process that keeps your terminal sessions alive after the window closes, is now something you switch on yourself. The same pull request fixes a deadlock that could leave the daemon stuck when you quit it on macOS. If you use daemon mode, both changes touch you.

Ask about this presentation

Chapters

  1. 0:00Daemon mode is opt-in
  2. 0:23Two defaults flip to false
  3. 0:44Your saved choice wins
  4. 1:08How to turn it back on
  5. 1:31Quitting on macOS
  6. 1:34Why quitting got stuck
  7. 1:57The hook leaves the tray alone
  8. 2:24Upgrade to 1.2.183
Show transcript
  1. BossTerm 1.2.183 changes a default you will notice. The session daemon, the background process that keeps your terminal sessions alive after the window closes, is now something you switch on yourself. The same pull request fixes a deadlock that could leave the daemon stuck when you quit it on macOS. If you use daemon mode, both changes touch you.

    Slide text
    ~/bossterm $ release v1.2.183
    daemon quit upgrade

    BossTerm 1.2.183 makes the session daemon opt-in

    It also fixes a deadlock when you quit the daemon on macOS.

    BossTerm logo
  2. Here is the change, in the defaults themselves. Daemon enabled, and start daemon at login, both flip from true to false. With the daemon off, your sessions, the MCP server and session sharing all run inside the BossTerm window, so they close when the window closes. That is the path BossTerm took before daemon mode existed.

    Slide text
    ~/bossterm $ release v1.2.183
    daemon quit upgrade

    Two daemon settings now start switched off

    compose-ui/…/settings/TerminalSettings.kt
    val daemonEnabled: Boolean = true
    val daemonEnabled: Boolean = false
    val startDaemonAtLogin: Boolean = true
    val startDaemonAtLogin: Boolean = false

    With the daemon off, sessions, MCP and sharing close with the window.

  3. Upgrading depends on what your settings file already says. A fresh install starts with the daemon off. A saved off stays off, and so does an older settings file that never mentioned the daemon. If your file says the daemon is on, it stays on. Earlier releases switched daemon mode on once for existing profiles. That one-time migration is gone, and its leftover marker now does nothing.

    Slide text
    ~/bossterm $ release v1.2.183
    daemon quit upgrade

    Upgrading keeps the daemon setting you saved

    Fresh install
    off
    Saved off
    stays off
    Older file, no daemon keys
    off
    Saved on
    stays on

    Removed: migrateDaemonModeDefault, the one-time switch-on for existing profiles

  4. If you want the daemon, it is one setting away. Switch daemon mode on in the session daemon settings. Then restart BossTerm, because the setting is read at startup. Turning it on also turns on start at login, which installs a launch agent on macOS, a systemd user unit on Linux, or a Run key on Windows. That has its own toggle if you want the daemon without it.

    Slide text
    ~/bossterm $ release v1.2.183
    daemon quit upgrade

    Want sessions that outlive the window? Turn the daemon on.

    1
    Switch daemon mode on
    in the session daemon settings
    2
    Restart BossTerm
    the setting is read at startup
    3
    Start at login comes on too
    LaunchAgent, systemd user unit or Run key. It has its own toggle.
  5. Now the fix, for quitting the daemon on a Mac.

    Slide text
    ~/bossterm $ release v1.2.183
    daemon quit upgrade
    fix

    Quitting the daemon on macOS

  6. Here is how it got stuck. A native macOS Quit can run System.exit on the AppKit thread, and that thread then waits for the shutdown hooks to return. The daemon's hook stopped its services and then removed the tray icon. Removing the tray icon needs the AppKit thread, which was busy waiting for the hook. Each side waited on the other, so the daemon could hang on the way out.

    Slide text
    ~/bossterm $ release v1.2.183
    daemon quit upgrade

    Quit on macOS could deadlock the daemon

    AppKit thread
    Quit → System.exit → waits for the shutdown hook
    Shutdown hook
    stop services → remove tray icon → waits for AppKit

    ↻ Each one waits on the other.

  7. The fix moves teardown into a small new class, DaemonShutdownLifecycle. The normal stop path stops the services, then removes the tray icon outside the service lock. The hook path only stops the services, and stays away from the user interface thread. The operating system removes the icon on exit. Either way, services stop exactly once. Four new tests cover it, including a hook that finishes while tray removal is blocked.

    Slide text
    ~/bossterm $ release v1.2.183
    daemon quit upgrade

    The shutdown hook now stops services and leaves the tray alone

    fun shutdown() {
        stopServicesOnce()
        removeTray()
    }
    
    fun shutdownFromHook() {
        stopServicesOnce()
    }

    DaemonShutdownLifecycle.kt
    new, 30 lines

    The OS removes the tray icon when the process exits.

    4 new tests, including a hook that finishes while tray removal is blocked

  8. Builds are out for macOS, Debian and Ubuntu, Fedora, Windows, and a JAR that runs on Java 17 or later. On a Mac, Homebrew installs it from the project's tap. The whole release is one pull request with these two changes. If you rely on sessions that outlive the window, open the session daemon settings after upgrading and make sure it is on. BossTerm 1.2.183 makes the session daemon opt-in, and quitting it on a Mac no longer deadlocks.

    Slide text
    ~/bossterm $ release v1.2.183
    daemon quit upgrade

    .dmg for macOS · .deb and .rpm for Linux, AMD64 and ARM64 · .msi for Windows · .jar on Java 17+

    $ brew tap kshivang/bossterm
    $ brew install --cask bossterm

    Rely on sessions that outlive the window? Check the daemon setting after upgrading.

    BossTerm on macOS

What happened in AI today, in your inbox

One short email each evening. Read it and you’re caught up.

Built in New York with ❤️