Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

gstack User Guide

Generated May 2026 from garrytan/gstack at e3d7f49

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Garry's Stack — the all-in-one AI engineering toolkit that gives your coding agent a real browser, a design studio, PDF rendering, and 30+ slash-command skills. Version 1.10.1.0, MIT licensed, built on Bun.

gstack bridges the gap between AI coding assistants and the real world: it lets agents browse the web, generate UI mockups, render PDFs, and execute structured engineering workflows — all from the command line. Whether you run Claude Code, OpenAI Codex CLI, Cursor, or any of eight other supported hosts, gstack plugs in and immediately expands what your agent can do.


1. Quick Start

Get gstack running in under two minutes.

Step 1 — Clone the repository:

git clone https://github.com/garrytan/gstack.git
cd gstack

Step 2 — Run setup:

./setup

This installs gstack skills into your AI host's skill directory (e.g., ~/.claude/skills/gstack/ for Claude Code), compiles the browse, design, and make-pdf binaries, and sets up the state directory at ~/.gstack/.

Step 3 — Launch the browser:

browse goto https://example.com

Expected output:

Navigated to https://example.com
Page loaded (200 OK)

Step 4 — Take a snapshot to see the page:

browse snapshot

Expected output:

[snapshot] 47 elements indexed
@e1  <h1> Example Domain
@e2  <p> This domain is for use in illustrative examples...
@e3  <a> More information...

Step 5 — Interact using element references:

browse click @e3

Tip

After running snapshot, every interactive element gets an @ref handle (like @e3). Use these refs with click, fill, hover, html, css, and attrs commands to interact precisely without writing CSS selectors.


2. Installation

2.1 Prerequisites

Requirement Minimum Version Notes
Bun 1.0.0 JavaScript/TypeScript runtime — bun.sh
Git Any recent For cloning the repository
Chromium Bundled via Playwright Installed automatically during setup

Optional dependencies:

Tool Required For
OpenAI API key design tool (GPT-4o image generation)
ngrok Tunnel support for remote browse access
pdftotext PDF text extraction in make-pdf pipeline

2.2 Install from Source

git clone https://github.com/garrytan/gstack.git
cd gstack
./setup

The setup script performs the following:

  1. Installs Bun dependencies (bun install)
  2. Builds the three binaries: browse, design, make-pdf
  3. Installs Playwright and its bundled Chromium
  4. Copies skills to the detected AI host's skill directory
  5. Creates ~/.gstack/ for state and configuration

Important

If you are installing into a specific AI host other than Claude Code, refer to the Multi-Host Setup section below. The setup script auto-detects your host, but you can override the target.

2.3 Building Binaries Manually

If you need to rebuild after pulling updates:

bun run build

This compiles all three entry points:

Binary Source Purpose
browse browse/src/cli.ts Headless Chromium browser CLI
design design/src/cli.ts AI-powered UI design tool
make-pdf make-pdf/src/cli.ts PDF rendering pipeline

2.4 Upgrading gstack

gstack includes a built-in upgrade skill with versioned migrations:

/gstack-upgrade

This runs the upgrade system, which applies any necessary migrations between your current version and the latest. You can also pull and rebuild manually:

cd ~/.claude/skills/gstack   # or wherever gstack is installed
git pull
./setup

2.5 Verifying Installation

browse status

Expected output when the server is running:

Server running on port 34567 (headed mode)
PID: 12345
Uptime: 2m 15s
Tabs: 1

If the server is not running, browse auto-starts it on the next command (unless BROWSE_NO_AUTOSTART=1).


3. Configuration

gstack is configured entirely through environment variables. There are no YAML, TOML, or INI config files.

3.1 Browse Configuration

Variable Default Description
BROWSE_PORT Random (34567 in headed) HTTP server listen port
BROWSE_HEADED 0 Set to 1 for headed Chromium (visible window)
BROWSE_IDLE_TIMEOUT Auto Server idle timeout before shutdown
BROWSE_TAB None Pin all commands to a specific tab ID
BROWSE_PARENT_PID Auto Set to 0 to disable parent-process watchdog
BROWSE_NO_AUTOSTART 0 Set to 1 to prevent auto-starting the server
BROWSE_BIN Auto-detected Override the browse binary path
BROWSE_CONTENT_FILTER None Content security filter level
BROWSE_TUNNEL Off Enable ngrok tunnel for remote access

3.2 Chromium and Security

Variable Default Description
GSTACK_CHROMIUM_PATH Playwright's bundled Chromium Path to a custom Chromium binary
GSTACK_SECURITY_ENSEMBLE Off Enable ML-based security ensemble classifier
GSTACK_SECURITY_OFF 0 Set to 1 to fully disable security classifier
GSTACK_HAIKU_TIMEOUT_MS Auto Timeout for the Haiku security classifier

3.3 Design Tool

Variable Default Description
OPENAI_API_KEY None OpenAI API key for GPT-4o image generation

Alternatively, store your key in ~/.gstack/openai.json:

{
  "api_key": "sk-..."
}

3.4 Other Variables

Variable Default Description
GSTACK_SLUG Auto Project slug identifier
GSTACK_SKILL_ROOT Auto Override the root directory for skill discovery
GSTACK_BROWSE_MAX_HTML_BYTES Auto Maximum HTML payload size for load-html
NGROK_AUTHTOKEN None ngrok authentication token for tunneling
NGROK_DOMAIN None Custom ngrok domain
SIDEBAR_AGENT_TIMEOUT Auto Timeout for sidebar agent operations
PDFTOTEXT_BIN Auto Override the pdftotext binary path

Note

For the complete list of all 84 environment variables and their internal behaviors, see the Admin Guide, Section: Environment Variable Reference.


4. Core Usage

gstack has three primary tools (browse, design, make-pdf) and a library of 30+ slash-command skills.

4.1 browse — Headless Chromium Browser

browse is a CLI-driven headless browser built on Playwright. It runs a persistent HTTP server that maintains browser state (cookies, tabs, sessions) across commands. AI coding agents use it to navigate websites, fill forms, take screenshots, and extract page content.

# Go to a URL
browse goto https://github.com

# Navigate back/forward
browse back
browse forward

# Reload the current page
browse reload

# Print the current URL
browse url

Reading Page Content

# Get all visible text
browse text

# Get HTML of the entire page or a specific element
browse html
browse html "#main-content"

# Get all links on the page
browse links

# Get all forms and their fields
browse forms

# Get the accessibility tree
browse accessibility

Interacting with Elements

# Click an element (CSS selector or @ref)
browse click "#submit-btn"
browse click @e3

# Fill a form field
browse fill "#email" "[email removed]"
browse fill @e4 "my search query"

# Select a dropdown option
browse select "#country" "United States"

# Hover over an element
browse hover @e1

# Type text (simulates keyboard input)
browse type "Hello, World!"

# Press a specific key
browse press Enter
browse press Tab

# Scroll the page or a specific element
browse scroll
browse scroll "#content-area"

# Upload files
browse upload "#file-input" ./report.pdf ./data.csv

# Wait for conditions
browse wait "#results"              # wait for element
browse wait --networkidle           # wait for network idle
browse wait --load                  # wait for page load

Viewport and Responsive Testing

# Set viewport dimensions
browse viewport 1920x1080
browse viewport 375x812

# Generate responsive screenshots at multiple breakpoints
browse responsive my-page

Expected output for responsive:

[responsive] Capturing at 375x812 (mobile)... saved my-page-375x812.png
[responsive] Capturing at 768x1024 (tablet)... saved my-page-768x1024.png
[responsive] Capturing at 1920x1080 (desktop)... saved my-page-1920x1080.png

Snapshots and Element References

The snapshot command is one of the most powerful features — it indexes every interactive element on the page and assigns @ref handles:

browse snapshot

Expected output:

[snapshot] 128 elements indexed
@e1   <nav>      Main navigation
@e2   <a>        Home
@e3   <a>        Products
@e4   <input>    Search... [text]
@e5   <button>   Sign In
@e6   <a>        Documentation
...

Snapshot options:

# Include invisible elements
browse snapshot -i

# Include cursor-interactive refs (@c1, @c2...)
browse snapshot -C

# Limit depth
browse snapshot -d 3

# Scope to a selector
browse snapshot -s "#sidebar"

# Include detailed attributes
browse snapshot -D

# Include accessibility info
browse snapshot -a

# Save to file
browse snapshot -o page-snapshot.txt

After a snapshot, @ref selectors work with most commands:

browse click @e5          # Click "Sign In" button
browse fill @e4 "gstack"  # Fill search input
browse hover @e2           # Hover "Home" link
browse html @e6            # Get HTML of "Documentation" link
browse css @e5 "color"     # Get CSS color of "Sign In"
browse attrs @e3           # Get all attributes of "Products"

When using the -C flag, cursor-interactive refs (@c1, @c2) are also available:

browse click @c1

Screenshots and PDFs

# Full-page screenshot
browse screenshot

# Viewport-only screenshot
browse screenshot --viewport

# Screenshot a specific element
browse screenshot @e1

# Clipped region
browse screenshot --clip 0,0,800,600

# Save to a specific path
browse screenshot ./captures/homepage.png

# Render page as PDF
browse pdf ./output/page.pdf

JavaScript Execution

# Evaluate a JavaScript expression
browse js "document.title"

# Run a JavaScript file
browse eval ./scripts/extract-data.js

Inspection

# Get CSS property value
browse css "#header" "background-color"

# Get element attributes
browse attrs "#logo"

# View console logs
browse console
browse console --errors    # errors only
browse console --clear     # clear and show

# View network requests
browse network
browse network --clear

# Handle dialogs
browse dialog              # show pending dialogs
browse dialog --clear
browse dialog-accept       # accept with optional text
browse dialog-accept "OK"
browse dialog-dismiss

# Check element state
browse is visible "#modal"
browse is hidden "#loading"
browse is enabled "#submit"
browse is checked "#agree-checkbox"
browse is focused "#search"

# Performance metrics
browse perf

# View/set cookies
browse cookies
browse cookie sessionId=abc123

# View/set storage
browse storage
browse storage set mykey myvalue

Tab Management

# List all open tabs
browse tabs

# Switch to a tab by ID
browse tab 2

# Open a new tab
browse newtab https://example.com

# Close a tab
browse closetab 2

Multi-Step Chains

Execute multiple browser actions in a single command by piping JSON from stdin:

echo '[
  {"action": "goto", "url": "https://example.com"},
  {"action": "snapshot"},
  {"action": "click", "selector": "@e3"},
  {"action": "screenshot", "path": "result.png"}
]' | browse chain

Page Comparison

browse diff https://staging.example.com https://production.example.com
# Import cookies from a JSON file
browse cookie-import ./cookies.json

# Import cookies from a local browser
browse cookie-import-browser chrome
browse cookie-import-browser firefox --domain github.com

Custom Headers and User Agent

# Set a custom header
browse header "Authorization: Bearer token123"

# Set a custom user agent
browse useragent "MyBot/1.0"

Headed Mode

Run Chromium with a visible window:

BROWSE_HEADED=1 browse goto https://example.com

Or connect/disconnect from an existing headed session:

browse connect
browse disconnect

Remote Pairing

Allow a remote agent to control your browse session:

browse pair-agent --client remote-agent --domain example.com --control
browse pair-agent --client remote-agent --restrict "navigation,content"
browse pair-agent --client remote-agent --local localhost:8080

Server Lifecycle

# Check server status
browse status

# Stop the server
browse stop

# Restart the server
browse restart

Tip

The browse server persists between commands and maintains state in .gstack/browse.json (PID, port, token, server path). If a command finds no running server, it auto-starts one unless BROWSE_NO_AUTOSTART=1 is set.

4.2 design — AI-Powered UI Design

The design tool generates UI mockups using OpenAI GPT-4o image generation. It requires an OpenAI API key.

Setup

Set your API key via environment variable or config file:

export OPENAI_API_KEY="sk-..."

Or create ~/.gstack/openai.json:

{
  "api_key": "sk-..."
}

Generate a Design

design generate "A modern dashboard for a SaaS analytics platform"

Iterate on an Existing Design

design iterate "Make the sidebar darker and add a notification bell icon"

Evolve a Design

design evolve "Transition from mobile layout to desktop"

Quality Check

Runs a vision-based quality gate using GPT-4o to evaluate text readability, layout completeness, and visual coherence:

design check

Compare and Diff

design compare
design diff

Design Variants

Generate multiple variations of a design concept:

design variants

View and serve your design history:

design gallery
design serve

Design to Code

Convert a generated design into HTML/CSS:

design design-to-code

Session Management

design session
design memory

4.3 make-pdf — PDF Rendering

make-pdf renders web pages and HTML content to PDF using Chromium under the hood:

make-pdf ./my-page.html ./output.pdf

It leverages the browse infrastructure for Chromium-based page rendering, ensuring pixel-perfect PDF output with full CSS support.

4.4 Skills — Slash Commands for AI Hosts

gstack installs 30+ skills as slash commands. In Claude Code, invoke them with /skill-name. Each skill has a SKILL.md file describing its purpose and usage.

Engineering Skills

Skill Purpose
/review Code review with structured feedback
/qa Quality assurance testing
/qa-only QA-only pass (no code changes)
/careful Extra-careful mode for critical changes
/guard Safety guard checks before deployment
/benchmark Performance benchmarking
/benchmark-models Benchmark across different AI models
/investigate Deep investigation of issues or behavior
/learn Extract and document learnings
/freeze Freeze current state
/unfreeze Unfreeze and resume

Design Skills

Skill Purpose
/design Generate UI designs
/design-consultation Design consultation and feedback
/design-html Generate HTML from design specs
/design-review Review design implementations
/design-shotgun Rapid-fire design exploration

Planning and Review Skills

Skill Purpose
/autoplan Automatic project planning
/plan-ceo-review CEO-level strategic plan review
/plan-design-review Design-focused plan review
/plan-devex-review Developer experience review
/plan-eng-review Engineering plan review
/plan-tune Fine-tune project plans
/cso Chief Strategy Officer analysis
/retro Retrospective analysis

Operations Skills

Skill Purpose
/ship Ship code to production
/land-and-deploy Land changes and deploy
/setup-deploy Configure deployment pipeline
/canary Canary deployment testing
/health Health check diagnostics

Productivity Skills

Skill Purpose
/context-save Save current context for later
/context-restore Restore previously saved context
/browse Launch browse from within your agent
/open-gstack-browser Open gstack browser in headed mode
/setup-browser-cookies Import browser cookies for authentication
/make-pdf Render content to PDF
/pair-agent Set up remote agent pairing
/office-hours Structured office hours workflow
/document-release Generate release documentation
/devex-review Developer experience review
/gstack-upgrade Upgrade gstack to the latest version
/codex OpenAI Codex integration

Note

The full list of skills and their detailed SKILL.md documentation is installed to your host's skill directory. For Claude Code, that is ~/.claude/skills/gstack/.


5. Common Tasks

5.1 Scraping a Web Page for Your AI Agent

A typical pattern for giving an AI agent web context:

# Navigate to the page
browse goto https://docs.example.com/api-reference

# Take a snapshot to index interactive elements
browse snapshot

# Extract the text content
browse text

For dynamic pages that need interaction first:

browse goto https://app.example.com/login
browse snapshot
browse fill @e2 "username"
browse fill @e3 "password"
browse click @e4
browse wait --networkidle
browse snapshot
browse text

5.2 Taking Screenshots for Visual Verification

# Full page
browse goto https://myapp.localhost:3000
browse screenshot ./screenshots/full-page.png

# Just the viewport
browse screenshot --viewport ./screenshots/viewport.png

# A specific component
browse snapshot
browse screenshot @e7 ./screenshots/nav-component.png

# Multiple responsive breakpoints
browse viewport 375x812
browse screenshot ./screenshots/mobile.png
browse viewport 1920x1080
browse screenshot ./screenshots/desktop.png

5.3 Filling Out Forms Automatically

browse goto https://example.com/register
browse snapshot

# Fill form fields using @refs
browse fill @e1 "Jane Doe"
browse fill @e2 "[email removed]"
browse fill @e3 "securepassword123"
browse select @e4 "United States"
browse click @e5   # checkbox: agree to terms
browse click @e6   # submit button

browse wait --networkidle
browse screenshot ./form-submitted.png

5.4 Installing Skills for Other AI Hosts

gstack supports 10 AI coding hosts. The ./setup script auto-detects your host, but you can also manually install skills.

Host Skill Install Location
Claude Code ~/.claude/skills/gstack/
OpenAI Codex CLI ~/.codex/skills/gstack/
Cursor ~/.cursor/skills/gstack/
Factory Droid ~/.factory/skills/gstack/
Kiro ~/.kiro/skills/gstack/
OpenCode ~/.config/opencode/skills/gstack/
Slate ~/.slate/skills/gstack/
OpenClaw ~/.openclaw/skills/gstack/
Hermes ~/.hermes/skills/gstack/
GBrain ~/.gbrain/skills/gstack/

After installation, use the host's CLI to invoke skills:

Host CLI Command Example
Claude Code claude /review
OpenAI Codex CLI codex /review
Cursor cursor /review
Factory Droid droid /review
Kiro kiro-cli /review
OpenCode opencode /review
Slate slate /review
OpenClaw openclaw /review
Hermes hermes /review
GBrain gbrain /review

5.5 Using the Design Tool for UI Mockups

A complete design workflow:

# Generate initial mockup
design generate "A settings page with dark mode toggle, notification preferences, and account deletion"

# Iterate on the result
design iterate "Move the delete account section to its own danger zone card at the bottom"

# Run quality check
design check

# Generate code from the approved design
design design-to-code

5.6 Rendering a Page to PDF

# Render an HTML file
make-pdf ./report.html ./report.pdf

# Or use browse directly for any URL
browse goto https://example.com/printable-report
browse pdf ./report.pdf

5.7 Running Code Review with Skills

In Claude Code:

/review

The review skill examines your current diff, provides structured feedback on code quality, potential bugs, and suggestions. For a more thorough pass:

/careful

5.8 Managing Browser Cookies for Authenticated Sessions

Import cookies from your local browser to access authenticated pages:

# Import all cookies from Chrome
browse cookie-import-browser chrome

# Import only cookies for a specific domain
browse cookie-import-browser chrome --domain github.com

# Import from a JSON export file
browse cookie-import ./exported-cookies.json

Or use the skill:

/setup-browser-cookies

5.9 Using ngrok Tunnels for Remote Access

Expose your local browse server to remote agents:

export NGROK_AUTHTOKEN="your-ngrok-token"
export BROWSE_TUNNEL=1

browse goto https://localhost:3000
browse status

With a custom domain:

export NGROK_DOMAIN="my-browse.ngrok.io"

5.10 Saving and Restoring Agent Context

Preserve your working context across sessions:

/context-save

Later, in a new session:

/context-restore

Tip

Context save/restore is especially useful when switching between tasks. Save before pivoting to a different feature, then restore when you return.


6. Troubleshooting

Error: Chromium not found

Cause: Playwright's bundled Chromium was not installed during setup, or a custom GSTACK_CHROMIUM_PATH points to a missing binary.

Solution:

  1. Run npx playwright install chromium from the gstack directory
  2. If using a custom path, verify it exists: ls $GSTACK_CHROMIUM_PATH
  3. Re-run ./setup to reinstall dependencies

Prevention: Always use ./setup for initial installation rather than manual bun install.

Error: Server not running or Connection refused

Cause: The browse server is not started or crashed.

Solution:

  1. Check status: browse status
  2. Check the state file: cat ~/.gstack/browse.json or .gstack/browse.json
  3. If stale, delete the state file and restart: rm .gstack/browse.json && browse goto https://example.com
  4. Check if the port is in use: lsof -i :34567 (Unix) or netstat -ano | findstr 34567 (Windows)

Prevention: Let browse auto-manage the server. Avoid killing processes manually.

Error: Port already in use

Cause: Another process (or a previous browse instance) is bound to the configured port.

Solution:

  1. Use a different port: BROWSE_PORT=34568 browse goto https://example.com
  2. Kill the existing process on the port
  3. Delete stale state: rm .gstack/browse.json

Prevention: Use the default random port assignment (don't set BROWSE_PORT) unless you specifically need a fixed port.

Error: DESIGN_NOT_AVAILABLE in Codex workflows

Cause: The design tool's fallback paths are broken when running under OpenAI Codex CLI (GitHub issue #1159).

Solution:

  1. Ensure OPENAI_API_KEY is set in your environment
  2. Verify the design binary exists: which design or check the build output
  3. Rebuild: bun run build
  4. Check that the Codex skill files reference the correct binary path

Prevention: After upgrading gstack, always run bun run build and verify all three binaries are compiled.

Error: Custom OPENAI_BASE_URL not respected

Cause: The design tool does not properly honor custom OpenAI base URLs (GitHub issue #957).

Solution:

  1. As a workaround, use the standard OpenAI endpoint
  2. If you must use a custom endpoint, check the design source for the exact variable handling
  3. Monitor issue #957 for an upstream fix

Prevention: Use the default OpenAI API endpoint when possible.

Error: build exit code 128 during Conductor template creation

Cause: Git operations fail during new project scaffolding, typically when the generated repo has an unborn HEAD (GitHub issues #1174, #1176).

Solution:

  1. Initialize the repo manually: git init && git add . && git commit -m "init"
  2. Then retry the Conductor template

Prevention: Ensure Git is properly configured (git config user.name and git config user.email are set) before using Conductor templates.

Error: setup --prefix does not work as expected

Cause: The --prefix flag has a known bug (GitHub issue #620).

Solution:

  1. Run ./setup without --prefix
  2. Manually move the installed files to your preferred location afterward

Prevention: Use the default installation path and adjust GSTACK_SKILL_ROOT if you need skills in a non-standard location.

Error: setup --help runs installation instead of showing help

Cause: The setup script does not support --help and interprets it as a normal run (GitHub issue #1133).

Solution:

  1. Read the setup script source directly: cat ./setup
  2. Refer to this User Guide for installation instructions

Prevention: Do not pass --help to the setup script.

Error: Snapshot returned 0 elements

Cause: The page content is loaded dynamically (SPA, lazy-loaded frames) and hasn't rendered yet.

Solution:

  1. Wait for content: browse wait --networkidle or browse wait "#target-element"
  2. Then retry: browse snapshot
  3. For iframes, try scoping: browse snapshot -s "iframe"

Prevention: Always add a wait step after navigation to dynamic pages before taking a snapshot.

Error: @ref not found or Invalid element reference

Cause: The @ref handle refers to a stale snapshot — the page has changed since the last snapshot command.

Solution:

  1. Run browse snapshot again to re-index elements
  2. Use the new @ref values

Prevention: Re-run snapshot after any page navigation, form submission, or significant DOM change.

Error: Timeout waiting for selector

Cause: The target element doesn't exist, is hidden, or the page is still loading.

Solution:

  1. Verify the element exists: browse html and search for it
  2. Wait longer: browse wait "#my-element"
  3. Check if the element is inside an iframe (iframes need special handling)
  4. Try a different selector strategy

Prevention: Use snapshot to discover actual selectors rather than guessing CSS selectors.

Error: Permission denied when running ./setup

Cause: The setup script doesn't have execute permission.

Solution:

  1. Add execute permission: chmod +x ./setup
  2. Or run directly: bash ./setup

Prevention: After cloning, run chmod +x ./setup before first use.

Error: bun: command not found

Cause: Bun is not installed or not on the system PATH.

Solution:

  1. Install Bun: curl -fsSL https://bun.sh/install | bash
  2. Restart your shell or source the profile: source ~/.bashrc
  3. Verify: bun --version (must be >= 1.0.0)

Prevention: Install Bun before running gstack setup.

Error: SECURITY: WARN verdict but no action taken

Cause: The security classifier issues WARN-level verdicts but does not take defensive action — it only logs the warning (GitHub issue #1156).

Solution:

  1. Review the warning manually in the console output
  2. If the content is safe, proceed normally
  3. If the content is suspicious, avoid interacting with it

Prevention: Enable the full security ensemble for stronger classification: export GSTACK_SECURITY_ENSEMBLE=1

Error: review skill not looking at correct diff

Cause: The review skill may examine the wrong diff when branches are complex (GitHub issue #1152).

Solution:

  1. Ensure you are on the correct branch
  2. Stage the changes you want reviewed: git add .
  3. Run /review again

Prevention: Commit or stage your changes before invoking the review skill.

Error: Session tracking not gated by telemetry config

Cause: Session tracking and the OPENCLAW_SESSION preamble run regardless of telemetry settings (GitHub issue #1150).

Solution:

  1. This is a known issue — telemetry gating will be fixed upstream
  2. The telemetry is anonymous and uses Supabase edge functions

Prevention: Monitor the issue tracker for a fix.

Error: Codex generated skills still carry Claude defaults

Cause: When skills are generated for Codex, some Claude-specific defaults persist (GitHub issue #1163).

Solution:

  1. Manually review generated skill files in ~/.codex/skills/gstack/
  2. Update any Claude-specific references to Codex equivalents

Prevention: Run bun run gen:skill-docs to regenerate skill docs for your specific host after installation.

Error: PDF rendering produces blank page

Cause: The page hasn't finished loading before PDF capture, or the page uses print-hostile CSS.

Solution:

  1. Wait for full load: browse wait --load
  2. Wait for network idle: browse wait --networkidle
  3. Then render: browse pdf ./output.pdf
  4. Try setting a larger viewport: browse viewport 1920x1080

Prevention: Always ensure the page is fully loaded before PDF rendering.

Warning

If browse commands hang indefinitely, the server may be deadlocked. Kill the process (browse stop), delete .gstack/browse.json, and restart. If the problem persists, check for Chromium zombie processes in your system's process manager.

Error: ngrok tunnel failed

Cause: Missing or invalid ngrok authentication.

Solution:

  1. Set your token: export NGROK_AUTHTOKEN="your-token"
  2. Verify your ngrok account at dashboard.ngrok.com
  3. Retry: BROWSE_TUNNEL=1 browse goto https://example.com

Prevention: Ensure NGROK_AUTHTOKEN is set before enabling tunnels.

Error: dialog: no pending dialog

Cause: The dialog was already handled, auto-dismissed, or never appeared.

Solution:

  1. Check dialog history: browse dialog
  2. Trigger the action that produces the dialog again
  3. Handle it immediately: browse dialog-accept or browse dialog-dismiss

Prevention: Handle dialogs promptly after the triggering action. Use browse dialog --clear to reset state.


7. FAQ

Q: What is gstack exactly? Is it a browser, a design tool, or an AI agent?

gstack is an AI engineering toolkit — a collection of tools and skills that enhance AI coding agents. Its three main tools are browse (headless browser), design (UI mockup generator), and make-pdf (PDF renderer). The 30+ skills are slash commands that add structured workflows (code review, QA, deployment, etc.) to your AI host.

Q: Which AI coding hosts does gstack support?

gstack supports 10 hosts: Claude Code, OpenAI Codex CLI, Cursor, Factory Droid, Kiro, OpenCode, Slate, OpenClaw, Hermes, and GBrain. Skills are installed to host-specific directories, and the setup script auto-detects your host.

Q: Do I need an OpenAI API key to use gstack?

Only for the design tool, which uses GPT-4o for image generation. The browse tool, make-pdf, and all other skills work without any API key.

Q: Is Chromium bundled, or do I need to install it separately?

Playwright installs a bundled Chromium during ./setup. You don't need to install Chrome or Chromium separately. If you prefer a custom Chromium binary, set GSTACK_CHROMIUM_PATH.

Q: How does the browse server work? Does it start and stop with each command?

The server is persistent. The first browse command starts it, and it stays running across subsequent commands. State (cookies, tabs, sessions) is maintained in .gstack/browse.json. The server shuts down on idle timeout or when you run browse stop. It auto-starts on the next command unless BROWSE_NO_AUTOSTART=1.

Q: What is headed mode and when should I use it?

Headed mode (BROWSE_HEADED=1) launches Chromium with a visible window so you can watch the browser in real time. It defaults to port 34567. Use it for debugging, demonstrations, or when you need to visually verify what the agent is doing. In headless mode (the default), Chromium runs invisibly with a random port.

Q: What are @ref selectors and how do they work?

After running browse snapshot, every interactive element on the page gets an @ref handle like @e1, @e3, @e15. These are stable shorthand for CSS selectors. Use them with click, fill, hover, html, css, and attrs. Refs become stale after page navigation — run snapshot again to refresh them.

Q: Can I use gstack to scrape websites behind authentication?

Yes. Import cookies from your local browser with browse cookie-import-browser chrome --domain example.com, or set cookies manually with browse cookie sessionId=abc123. You can also fill login forms directly with browse fill commands.

Q: How do I use gstack with a remote machine or server?

Enable ngrok tunneling with BROWSE_TUNNEL=1 and NGROK_AUTHTOKEN. For agent-to-agent collaboration, use browse pair-agent. You can also forward a specific port with BROWSE_PORT.

Q: What does the security classifier do?

gstack includes a content security classifier that evaluates pages for malicious content. It runs automatically during browse operations. You can enable the full ML ensemble with GSTACK_SECURITY_ENSEMBLE=1 or disable it entirely with GSTACK_SECURITY_OFF=1. The classifier issues verdicts (SAFE, WARN, BLOCK) but WARN verdicts currently do not trigger defensive actions.

Q: How do I update gstack?

Run the /gstack-upgrade skill from your AI host, or manually: cd into the gstack directory, git pull, and run ./setup again. The upgrade system includes versioned migrations that handle any necessary state changes.

Q: What data does gstack's telemetry collect?

gstack collects anonymous usage analytics via Supabase edge functions. This includes session-level usage data, not personal information. Telemetry gating is being improved (see issue #1150).

Q: Can I use browse without an AI coding host?

Yes. browse is a standalone CLI tool. You can use it directly from any terminal without Claude Code, Codex, or any other AI host. The skills (slash commands) require a host, but the core tools work independently.

Q: What is the snapshot -C flag for?

The -C flag adds cursor-interactive refs (@c1, @c2, etc.) in addition to the standard @e refs. These represent elements that are interactive based on cursor behavior (hover targets, clickable areas) that might not have standard form-element semantics.

Caution

The browse tool can interact with any website your network can reach. Be mindful of terms of service when using it for automated interactions. Do not use it for unauthorized access or aggressive scraping.

Q: Where does gstack store its state?

State is stored in two locations: ~/.gstack/ (global — API keys, shared config) and .gstack/ (project-local — browse.json with server PID/port/token). The project-local directory is created in your current working directory.

Q: How do I check which skills are installed?

Run bun run skill:check from the gstack directory. You can also list the skill directories in your host's skill root (e.g., ls ~/.claude/skills/gstack/).