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

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 (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 (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 (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 (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:

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 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:

/restart

This command invokes the same meta-command handler in meta-commands.ts that the auto-restart mechanism uses.

Programmatic Version Check

To implement similar version validation in custom scripts:

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 to detect binary updates.
  • Version mismatches trigger automatic restarts through 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 (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.

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) differs from the version stored in the daemon's state file. This comparison occurs during every command execution in browse/src/cli.ts.

Does the restart preserve my original command-line flags?

Yes. According to the implementation in 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.

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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →