# How GStack's Version Auto-Restart Mechanism Works: Automatic Daemon Updates Explained

> Learn how GStack's version auto-restart mechanism automatically updates daemons. Discover seamless updates without manual intervention for the garrytan/gstack repository.

- Repository: [Garry Tan/gstack](https://github.com/garrytan/gstack)
- Tags: internals
- Published: 2026-05-15

---

**GStack automatically restarts the *browse* daemon whenever the CLI detects a version mismatch between the installed binary and the running daemon's state file, ensuring seamless updates without manual intervention.**

The **gstack version auto-restart mechanism** is a built-in safety feature in the `garrytan/gstack` repository that keeps the browser automation daemon synchronized with the CLI binary. This system prevents version drift by monitoring the bundled version string and orchestrating a graceful shutdown and relaunch cycle whenever updates are detected.

## How the Auto-Restart Mechanism Works

The gstack version auto-restart mechanism operates through a four-step workflow that triggers during every CLI command execution. This process ensures that the daemon always runs the same version as the controlling CLI binary.

### Step 1: Binary Version Detection

When the CLI initializes, it reads the embedded version identifier from the distributed binary. In [`browse/src/config.ts`](https://github.com/garrytan/gstack/blob/main/browse/src/config.ts) (lines 145-151), the system accesses the version string stored at `browse/dist/.version` and compares it against the version persisted in the daemon's state file.

### Step 2: Version Mismatch Detection

During command execution in [`browse/src/cli.ts`](https://github.com/garrytan/gstack/blob/main/browse/src/cli.ts) (lines 348-353), the CLI performs a strict equality check between the current binary version and the daemon's recorded version. If the values differ, the CLI logs the diagnostic message `[browse] Binary updated, restarting server…` (line 351) and initiates the restart sequence rather than executing the requested command.

### Step 3: Graceful Daemon Shutdown

The CLI dispatches a **restart meta-command** to the daemon process. In [`browse/src/meta-commands.ts`](https://github.com/garrytan/gstack/blob/main/browse/src/meta-commands.ts) (lines 418-420), this command is handled by logging the request and calling `process.exit()`, outputting `[browse] Restart requested. Exiting for CLI to restart.` This ensures the daemon terminates cleanly without orphaning browser instances.

### Step 4: Daemon Relaunch with Original Flags

After detecting the daemon's exit, the CLI automatically relaunches the server using `startServer` in [`browse/src/cli.ts`](https://github.com/garrytan/gstack/blob/main/browse/src/cli.ts) (lines 505-509). The restart preserves all originally supplied flags—including `--proxy` and `--headed` options—by passing the saved `restartEnv` environment variables to the new process instance.

## Configuring the Auto-Upgrade Flag

The **auto-upgrade flag** (`auto_upgrade`) controls whether the CLI automatically performs version-based restarts or exits with an error code. You can manage this setting via the `gstack-config` command-line tool.

Enable automatic restarts when binaries update:

```bash
gstack-config set auto_upgrade true

```

When `auto_upgrade` is set to `false`, the CLI aborts with a non-zero exit code upon detecting a version mismatch instead of triggering the restart cycle. The [`test/team-mode.test.ts`](https://github.com/garrytan/gstack/blob/main/test/team-mode.test.ts) file contains test coverage validating both behaviors of this flag.

## Practical Code Examples

### Typical Auto-Restart Output

When gstack detects a binary update, the CLI outputs:

```

[browse] Binary updated, restarting server...

```

This message indicates the version mismatch was detected and the restart sequence initiated.

### Manual Restart via Meta-Command

During an active CLI session, you can manually trigger the restart logic:

```bash
/restart

```

This command invokes the same meta-command handler in [`meta-commands.ts`](https://github.com/garrytan/gstack/blob/main/meta-commands.ts) that the auto-restart mechanism uses.

### Programmatic Version Check

To implement similar version validation in custom scripts:

```typescript
import { readFileSync } from 'fs';
import { execSync } from 'child_process';
import path from 'path';

const stateVersion = readFileSync(path.resolve(stateDir, 'version'), 'utf-8');
const binaryVersion = execSync('gstack --version').toString().trim();

if (stateVersion !== binaryVersion) {
  console.error('[browse] Binary updated, restarting server...');
  // Trigger restart logic as implemented in browse/src/cli.ts
}

```

## Summary

- The **gstack version auto-restart mechanism** monitors `browse/dist/.version` via [`browse/src/config.ts`](https://github.com/garrytan/gstack/blob/main/browse/src/config.ts) to detect binary updates.
- Version mismatches trigger automatic restarts through [`browse/src/cli.ts`](https://github.com/garrytan/gstack/blob/main/browse/src/cli.ts) (lines 348-353) by comparing daemon state against the current binary.
- The restart sequence uses a meta-command defined in [`browse/src/meta-commands.ts`](https://github.com/garrytan/gstack/blob/main/browse/src/meta-commands.ts) (lines 418-420) to gracefully shut down the daemon.
- Original CLI flags are preserved during restart through the `restartEnv` variable passed to `startServer` (lines 505-509).
- The `auto_upgrade` configuration flag toggles between automatic restart and error-exit behaviors, tested in [`team-mode.test.ts`](https://github.com/garrytan/gstack/blob/main/team-mode.test.ts).

## Frequently Asked Questions

### What triggers the gstack auto-restart mechanism?

The mechanism triggers when the CLI detects that the version string in `browse/dist/.version` (read via [`browse/src/config.ts`](https://github.com/garrytan/gstack/blob/main/browse/src/config.ts)) differs from the version stored in the daemon's state file. This comparison occurs during every command execution in [`browse/src/cli.ts`](https://github.com/garrytan/gstack/blob/main/browse/src/cli.ts).

### Does the restart preserve my original command-line flags?

Yes. According to the implementation in [`browse/src/cli.ts`](https://github.com/garrytan/gstack/blob/main/browse/src/cli.ts) (lines 505-509), the restart logic captures all original flags—including `--proxy` and `--headed` options—in the `restartEnv` variable and passes them to the new daemon instance.

### How do I disable automatic restarts?

Set the `auto_upgrade` flag to `false` using `gstack-config set auto_upgrade false`. When disabled, the CLI exits with a non-zero status code upon version mismatch rather than restarting the daemon, as validated in [`test/team-mode.test.ts`](https://github.com/garrytan/gstack/blob/main/test/team-mode.test.ts).

### Does this mechanism work in both headless and headed modes?

Yes. Because the restart is orchestrated by the CLI's version comparison logic before any browser-specific code executes, it functions identically for both headless and headed browser configurations.