Skills Agentes

Open Gstack Browser

Lanza GStack Browser: un Chromium controlado por IA con la extensión de panel lateral integrada.

Solicitabashreadaskuserquestion
Estrellas
129k

en todo el repo

Actividad
77

0–100, la ruta de este skill

Actualizado
anteayer

último commit aquí

Commits
17

últimos 90 días

Contexto
9.3k tok

21 tok en reposo

Paquete
2 archivos

44 KB

Instalar

Funciona con cualquier agente que lea SKILL.md

npx -y skills add garrytan/gstack --skill open-gstack-browser --agent claude-code

Se instala solo en este repositorio.

Este skill runs shell commands, makes network requests, reads environment config.

Qué hace

  • Launches GStack Browser, a rebranded Chromium in headed mode via `$B connect`, with the sidebar extension auto-loaded
  • Shows a live activity feed and sidebar chat panel reflecting every browser action in real time
  • Applies anti-bot stealth patches so sites like Google and NYTimes work without captchas
  • Guides the user through pinning and opening the Side Panel extension
  • Runs a demo (`goto` + `snapshot`) then explains `$B focus`, `$B disconnect`, and other browse commands

Úsalo cuando

  • User asks to 'open gstack browser', 'launch browser', 'connect chrome', 'open chrome', 'real browser', 'launch chrome', 'side panel', or 'control my browser'
  • Voice trigger: 'show me the browser'

No lo uses cuando

    Qué lo activa

    Di cualquiera de estas frases y el agente debería cargar este skill.

    • Abre gstack browser
    • Lanza chromium para ver la navegación en vivo
    • Conecta chrome para el side panel
    • Muéstrame el navegador

    SKILL.md

    En inglés

    When to invoke this skill

    Opens a visible browser window where you can watch every action in real time. The sidebar shows a live activity feed and chat. Anti-bot stealth built in. Use when asked to "open gstack browser", "launch browser", "connect chrome", "open chrome", "real browser", "launch chrome", "side panel", or "control my browser".

    Voice triggers (speech-to-text aliases): "show me the browser".

    Preamble (run first)

    _UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true)
    [ -n "$_UPD" ] && echo "$_UPD" || true
    mkdir -p ~/.gstack/sessions
    touch ~/.gstack/sessions/"$PPID"
    _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
    find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true
    _PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
    _PROACTIVE_PROMPTED=$([ -f ~/.gstack/.proactive-prompted ] && echo "yes" || echo "no")
    _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
    echo "BRANCH: $_BRANCH"
    _SKILL_PREFIX=$(~/.claude/skills/gstack/bin/gstack-config get skill_prefix 2>/dev/null || echo "false")
    echo "PROACTIVE: $_PROACTIVE"
    echo "PROACTIVE_PROMPTED: $_PROACTIVE_PROMPTED"
    echo "SKILL_PREFIX: $_SKILL_PREFIX"
    source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
    REPO_MODE=${REPO_MODE:-unknown}
    echo "REPO_MODE: $REPO_MODE"
    _SESSION_KIND=$(~/.claude/skills/gstack/bin/gstack-session-kind 2>/dev/null || echo "interactive")
    case "$_SESSION_KIND" in spawned|headless|interactive) ;; *) _SESSION_KIND="interactive" ;; esac
    echo "SESSION_KIND: $_SESSION_KIND"
    # Conductor host: AskUserQuestion is unreliable here (native disabled, MCP
    # variant flaky), so skills render decisions as prose instead of calling the
    # tool. Gated on !headless so an eval/CI run INSIDE Conductor (GSTACK_HEADLESS)
    # still BLOCKs rather than rendering prose to nobody.
    if [ "$_SESSION_KIND" != "headless" ] && { [ -n "${CONDUCTOR_WORKSPACE_PATH:-}" ] || [ -n "${CONDUCTOR_PORT:-}" ]; }; then
      echo "CONDUCTOR_SESSION: true"
    fi
    _ACTIVATED=$([ -f ~/.gstack/.activated ] && echo "yes" || echo "no")
    _FIRST_LOOP_SHOWN=$([ -f ~/.gstack/.first-loop-tip-shown ] && echo "yes" || echo "no")
    echo "ACTIVATED: $_ACTIVATED"
    echo "FIRST_LOOP_SHOWN: $_FIRST_LOOP_SHOWN"
    # First-run project detection: run the detector ONLY on the first-ever skill run
    # (ACTIVATED=no, interactive) so it stays off the hot path for every run after.
    _FIRST_TASK=""
    if [ "$_ACTIVATED" = "no" ] && [ "$_SESSION_KIND" != "headless" ]; then
      _FIRST_TASK=$(~/.claude/skills/gstack/bin/gstack-first-task-detect 2>/dev/null || true)
    fi
    echo "FIRST_TASK: $_FIRST_TASK"
    _LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
    echo "LAKE_INTRO: $_LAKE_SEEN"
    _TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
    _TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no")
    _TEL_START=$(date +%s)
    _SESSION_ID="$$-$(date +%s)"
    echo "TELEMETRY: ${_TEL:-off}"
    echo "TEL_PROMPTED: $_TEL_PROMPTED"
    _EXPLAIN_LEVEL=$(~/.claude/skills/gstack/bin/gstack-config get explain_level 2>/dev/null || echo "default")
    if [ "$_EXPLAIN_LEVEL" != "default" ] && [ "$_EXPLAIN_LEVEL" != "terse" ]; then _EXPLAIN_LEVEL="default"; fi
    echo "EXPLAIN_LEVEL: $_EXPLAIN_LEVEL"
    _QUESTION_TUNING=$(~/.claude/skills/gstack/bin/gstack-config get question_tuning 2>/dev/null || echo "false")
    echo "QUESTION_TUNING: $_QUESTION_TUNING"
    _UPDATE_CHECK=$(~/.claude/skills/gstack/bin/gstack-config get update_check 2>/dev/null || echo "true")
    echo "UPDATE_CHECK: $_UPDATE_CHECK"
    mkdir -p ~/.gstack/analytics
    if [ "$_TEL" != "off" ]; then
    echo '{"skill":"open-gstack-browser","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(_repo=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null | tr -cd 'a-zA-Z0-9._-'); echo "${_repo:-unknown}")'"}'  >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
    fi
    for _PF in $(find ~/.gstack/analytics -maxdepth 1 -name '.pending-*' 2>/dev/null); do
      if [ -f "$_PF" ]; then
        if [ "$_TEL" != "off" ] && [ -x "$HOME/.claude/skills/gstack/bin/gstack-telemetry-log" ]; then
          ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true
        fi
        rm -f "$_PF" 2>/dev/null || true
      fi
      break
    done
    eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true
    _LEARN_FILE="${GSTACK_HOME:-$HOME/.gstack}/projects/${SLUG:-unknown}/learnings.jsonl"
    if [ -f "$_LEARN_FILE" ]; then
      _LEARN_COUNT=$(wc -l < "$_LEARN_FILE" 2>/dev/null | tr -d ' ')
      echo "LEARNINGS: $_LEARN_COUNT entries loaded"
      if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
        ~/.claude/skills/gstack/bin/gstack-learnings-search --limit 3 2>/dev/null || true
      fi
    else
      echo "LEARNINGS: 0"
    fi
    ~/.claude/skills/gstack/bin/gstack-timeline-log '{"skill":"open-gstack-browser","event":"started","branch":"'"$_BRANCH"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null &
    _HAS_ROUTING="no"
    for _RF in CLAUDE.md AGENTS.md; do
      if [ -f "$_RF" ] && grep -q "## Skill routing" "$_RF" 2>/dev/null; then
        _HAS_ROUTING="yes"
      fi
    done
    _ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false")
    echo "HAS_ROUTING: $_HAS_ROUTING"
    echo "ROUTING_DECLINED: $_ROUTING_DECLINED"
    _VENDORED="no"
    if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
      if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then
        _VENDORED="yes"
      fi
    fi
    echo "VENDORED_GSTACK: $_VENDORED"
    echo "MODEL_OVERLAY: claude"
    _CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
    _CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
    echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
    echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
    # Plan-mode hint for skills like /spec that branch behavior on plan-mode state.
    # Claude Code exposes plan mode via system reminders; we detect best-effort
    # from CLAUDE_PLAN_FILE (set by the harness when plan mode is active) and
    # fall back to "inactive". Codex hosts and Claude execution mode both end up
    # inactive, which is the safe default (defaults to file+execute pipeline).
    if [ -n "${CLAUDE_PLAN_FILE:-}${GSTACK_PLAN_MODE_FORCE:-}" ]; then
      export GSTACK_PLAN_MODE="active"
    elif [ "${GSTACK_PLAN_MODE:-}" = "active" ]; then
      export GSTACK_PLAN_MODE="active"
    else
      export GSTACK_PLAN_MODE="inactive"
    fi
    echo "GSTACK_PLAN_MODE: $GSTACK_PLAN_MODE"
    [ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
    

    Plan Mode Safe Operations

    In plan mode, allowed because they inform the plan: $B, $D, codex exec/codex review, writes to ~/.gstack/, writes to the plan file, and open for generated artifacts.

    Skill Invocation During Plan Mode

    If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. Treat the skill file as executable instructions, not reference. Follow it step by step starting from Step 0; any AskUserQuestion the skill fires is the workflow operating within plan mode, not a violation of it — and a skill whose instructions resolve a question themselves (e.g. a plan-mode auto-select) may legitimately not ask it. AskUserQuestion (any variant — mcp__*__AskUserQuestion or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If AskUserQuestion is unavailable or a call fails, follow the AskUserQuestion Format failure fallback: headless → BLOCKED; interactive → the prose fallback (also satisfies end-of-turn). At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.

    If PROACTIVE is "false", do not auto-invoke or proactively suggest skills. If a skill seems useful, ask: "I think /skillname might help here — want me to run it?"

    If SKILL_PREFIX is "true", suggest/invoke /gstack-* names. Disk paths stay ~/.claude/skills/gstack/[skill-name]/SKILL.md.

    If UPDATE_CHECK is "false", skip the next two lines — the update-check binary emits nothing in that mode, so there is no UPGRADE_AVAILABLE / JUST_UPGRADED output to act on.

    If output shows UPGRADE_AVAILABLE <old> <new>: read ~/.claude/skills/gstack/gstack-upgrade/SKILL.md and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined).

    If output shows JUST_UPGRADED <from> <to>: print "Running gstack v{to} (just updated!)". If SPAWNED_SESSION is true, skip feature discovery.

    Feature discovery, max one prompt per session:

    • Missing ~/.claude/skills/gstack/.feature-prompted-continuous-checkpoint: AskUserQuestion for Continuous checkpoint auto-commits. If accepted, run ~/.claude/skills/gstack/bin/gstack-config set checkpoint_mode continuous. Always touch marker.
    • Missing ~/.claude/skills/gstack/.feature-prompted-model-overlay: inform "Model overlays are active. MODEL_OVERLAY shows the patch." Always touch marker.

    After upgrade prompts, continue workflow.

    If WRITING_STYLE_PENDING is yes: ask once about writing style:

    v1 prompts are simpler: first-use jargon glosses, outcome-framed questions, shorter prose. Keep default or restore terse?

    Options:

    • A) Keep the new default (recommended — good writing helps everyone)
    • B) Restore V0 prose — set explain_level: terse

    If A: leave explain_level unset (defaults to default). If B: run ~/.claude/skills/gstack/bin/gstack-config set explain_level terse.

    Always run (regardless of choice):

    rm -f ~/.gstack/.writing-style-prompt-pending
    touch ~/.gstack/.writing-style-prompted
    

    Skip if WRITING_STYLE_PENDING is no.

    If LAKE_INTRO is no: say "gstack follows the Boil the Ocean principle — do the complete thing when AI makes marginal cost near-zero. Read more: https://garryslist.org/posts/boil-the-ocean" Offer to open:

    open https://garryslist.org/posts/boil-the-ocean
    touch ~/.gstack/.completeness-intro-seen
    

    Only run open if yes. Always run touch.

    If TEL_PROMPTED is no AND LAKE_INTRO is yes: ask telemetry once via AskUserQuestion:

    Help gstack get better. Share usage data only: skill, duration, crashes, stable device ID. No code or file paths. Your repo name is recorded locally only and stripped before any upload.

    Options:

    • A) Help gstack get better! (recommended)
    • B) No thanks

    If A: run ~/.claude/skills/gstack/bin/gstack-config set telemetry community

    If B: ask follow-up:

    Anonymous mode sends only aggregate usage, no unique ID.

    Options:

    • A) Sure, anonymous is fine
    • B) No thanks, fully off

    If B→A: run ~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous If B→B: run ~/.claude/skills/gstack/bin/gstack-config set telemetry off

    Always run:

    touch ~/.gstack/.telemetry-prompted
    

    Skip if TEL_PROMPTED is yes.

    If PROACTIVE_PROMPTED is no AND TEL_PROMPTED is yes: ask once:

    Let gstack proactively suggest skills, like /qa for "does this work?" or /investigate for bugs?

    Options:

    • A) Keep it on (recommended)
    • B) Turn it off — I'll type /commands myself

    If A: run ~/.claude/skills/gstack/bin/gstack-config set proactive true If B: run ~/.claude/skills/gstack/bin/gstack-config set proactive false

    Always run:

    touch ~/.gstack/.proactive-prompted
    

    Skip if PROACTIVE_PROMPTED is yes.

    First-run guidance (one-time)

    If ACTIVATED is no (first skill run on this machine) AND the preamble printed a non-empty FIRST_TASK: value that is NOT nongit: show ONE short, project-specific line mapped from the token, as a heads-up, then CONTINUE with whatever the user actually asked — do NOT halt their task. Map the token: greenfield → "Fresh repo — shape it first with /spec or /office-hours." code_node/code_python/code_rust/code_go/code_ruby/code_ios → "There's code here — /qa to see it work, or /investigate if something's off." branch_ahead → "Unshipped work on this branch — /review then /ship." dirty_default → "Uncommitted changes — /review before committing." clean_default → "Pick one: /spec, /investigate, or /qa." Then substitute the token you saw for TASK_TOKEN and run (best-effort), and mark activated:

    ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type first_task_scaffold_shown --skill "TASK_TOKEN" --outcome shown 2>/dev/null || true
    touch ~/.gstack/.activated 2>/dev/null || true
    

    If ACTIVATED is no but FIRST_TASK: is empty or nongit (headless, non-git, or nothing actionable): show nothing, just run touch ~/.gstack/.activated 2>/dev/null || true.

    Else if ACTIVATED is yes AND FIRST_LOOP_SHOWN is no: say once as a heads-up (then continue):

    Tip: gstack pays off when you complete one loop — plan → review → ship. A common first loop: /office-hours or /spec to shape it, /plan-eng-review to lock it, then /ship.

    Then run touch ~/.gstack/.first-loop-tip-shown 2>/dev/null || true.

    Skip this section if ACTIVATED and FIRST_LOOP_SHOWN are both yes.

    If HAS_ROUTING is no AND ROUTING_DECLINED is false AND PROACTIVE_PROMPTED is yes: Check if a CLAUDE.md file exists in the project root. If it does not exist, create it.

    Use AskUserQuestion:

    gstack works best when your project's CLAUDE.md includes skill routing rules.

    Options:

    • A) Add routing rules to CLAUDE.md (recommended)
    • B) No thanks, I'll invoke skills manually

    If A: Append this section to the end of CLAUDE.md:

    
    ## Skill routing
    
    When the user's request matches an available skill, invoke it via the Skill tool. When in doubt, invoke the skill.
    
    Key routing rules:
    - Product ideas/brainstorming → invoke /office-hours
    - Strategy/scope → invoke /plan-ceo-review
    - Architecture → invoke /plan-eng-review
    - Design system/plan review → invoke /design-consultation or /plan-design-review
    - Full review pipeline → invoke /autoplan
    - Bugs/errors → invoke /investigate
    - QA/testing site behavior → invoke /qa or /qa-only
    - Code review/diff check → invoke /review
    - Visual polish → invoke /design-review
    - Ship/deploy/PR → invoke /ship or /land-and-deploy
    - Save progress → invoke /context-save
    - Resume context → invoke /context-restore
    - Author a backlog-ready spec/issue → invoke /spec
    

    Then commit the change: git add CLAUDE.md && git commit -m "chore: add gstack skill routing rules to CLAUDE.md"

    If B: run ~/.claude/skills/gstack/bin/gstack-config set routing_declined true and say they can re-enable with gstack-config set routing_declined false.

    This only happens once per project. Skip if HAS_ROUTING is yes or ROUTING_DECLINED is true.

    If VENDORED_GSTACK is yes, warn once via AskUserQuestion unless ~/.gstack/.vendoring-warned-$SLUG exists:

    This project has gstack vendored in .claude/skills/gstack/. Vendoring is deprecated. Migrate to team mode?

    Options:

    • A) Yes, migrate to team mode now
    • B) No, I'll handle it myself

    If A:

    1. Run git rm -r .claude/skills/gstack/
    2. Run echo '.claude/skills/gstack/' >> .gitignore
    3. Run ~/.claude/skills/gstack/bin/gstack-team-init required (or optional)
    4. Run git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"
    5. Tell the user: "Done. Each developer now runs: cd ~/.claude/skills/gstack && ./setup --team"

    If B: say "OK, you're on your own to keep the vendored copy up to date."

    Always run (regardless of choice):

    eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true
    touch ~/.gstack/.vendoring-warned-${SLUG:-unknown}
    

    If marker exists, skip.

    If SPAWNED_SESSION is "true", you are running inside a session spawned by an AI orchestrator (e.g., OpenClaw). In spawned sessions:

    • Do NOT use AskUserQuestion for interactive prompts. Auto-choose the recommended option.
    • Do NOT run upgrade checks, telemetry prompts, routing injection, or lake intro.
    • Focus on completing the task and reporting results via prose output.
    • End with a completion report: what shipped, decisions made, anything uncertain.

    Artifacts Sync (skill start)

    _GSTACK_HOME="${GSTACK_HOME:-$HOME/.gstack}"
    # Prefer the v1.27.0.0 artifacts file; fall back to brain file for users
    # upgrading mid-stream before the migration script runs.
    if [ -f "$HOME/.gstack-artifacts-remote.txt" ]; then
      _BRAIN_REMOTE_FILE="$HOME/.gstack-artifacts-remote.txt"
    else
      _BRAIN_REMOTE_FILE="$HOME/.gstack-brain-remote.txt"
    fi
    _BRAIN_SYNC_BIN="$HOME/.claude/skills/gstack/bin/gstack-brain-sync"
    _BRAIN_CONFIG_BIN="$HOME/.claude/skills/gstack/bin/gstack-config"
    
    # /sync-gbrain context-load: teach the agent to use gbrain when it's available.
    # Per-worktree pin: post-spike redesign uses kubectl-style `.gbrain-source` in the
    # git toplevel to scope queries. Look for the pin in the worktree (not a global
    # state file) so that opening worktree B without a pin doesn't claim "indexed"
    # just because worktree A was synced. Empty string when gbrain is not
    # configured (zero context cost for non-gbrain users).
    _GBRAIN_CONFIG="$HOME/.gbrain/config.json"
    if [ -f "$_GBRAIN_CONFIG" ] && command -v gbrain >/dev/null 2>&1; then
      _GBRAIN_VERSION_OK=$(gbrain --version 2>/dev/null | grep -c '^gbrain ' || echo 0)
      if [ "$_GBRAIN_VERSION_OK" -gt 0 ] 2>/dev/null; then
        _GBRAIN_PIN_PATH=""
        _REPO_TOP=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
        if [ -n "$_REPO_TOP" ] && [ -f "$_REPO_TOP/.gbrain-source" ]; then
          _GBRAIN_PIN_PATH="$_REPO_TOP/.gbrain-source"
        fi
        if [ -n "$_GBRAIN_PIN_PATH" ]; then
          echo "GBrain configured. Prefer \`gbrain search\`/\`gbrain query\` over Grep for"
          echo "semantic questions; use \`gbrain code-def\`/\`code-refs\`/\`code-callers\` for"
          echo "symbol-aware code lookup. See \"## GBrain Search Guidance\" in CLAUDE.md."
          echo "Run /sync-gbrain to refresh."
        else
          echo "GBrain configured but this worktree isn't pinned yet. Run \`/sync-gbrain --full\`"
          echo "before relying on \`gbrain search\` for code questions in this worktree."
          echo "Falls back to Grep until pinned."
        fi
      fi
    fi
    
    _BRAIN_SYNC_MODE=$("$_BRAIN_CONFIG_BIN" get artifacts_sync_mode 2>/dev/null || echo off)
    
    # Detect remote-MCP mode (Path 4 of /setup-gbrain). Local artifacts sync is
    # a no-op in remote mode; the brain server pulls from GitHub/GitLab on its
    # own cadence. Read claude.json directly to keep this preamble fast (no
    # subprocess to claude CLI on every skill start). Both registration scopes
    # are read (#2499): user scope, then the nearest-ancestor project scope.
    _GBRAIN_MCP_MODE="none"
    _GBRAIN_MCP_ENTRY=""
    if command -v jq >/dev/null 2>&1 && [ -f "$HOME/.claude.json" ]; then
      _GBRAIN_MCP_ENTRY=$(jq -c --arg cwd "$PWD" '((.projects // {}) | to_entries | map(select((.key as $k | $cwd == $k or ($cwd | startswith($k + "/")) or ($cwd | startswith($k + "\\"))) and ((try .value.mcpServers.gbrain catch null) != null))) | sort_by(.key | length) | last | .value.mcpServers.gbrain) // .mcpServers.gbrain // empty' "$HOME/.claude.json" 2>/dev/null)
      _GBRAIN_MCP_TYPE=$(printf '%s' "$_GBRAIN_MCP_ENTRY" | jq -r '.type // .transport // empty' 2>/dev/null)
      case "$_GBRAIN_MCP_TYPE" in
        url|http|sse) _GBRAIN_MCP_MODE="remote-http" ;;
        stdio) _GBRAIN_MCP_MODE="local-stdio" ;;
      esac
    fi
    
    if [ -f "$_BRAIN_REMOTE_FILE" ] && [ ! -d "$_GSTACK_HOME/.git" ] && [ "$_BRAIN_SYNC_MODE" = "off" ]; then
      _BRAIN_NEW_URL=$(head -1 "$_BRAIN_REMOTE_FILE" 2>/dev/null | tr -d '[:space:]')
      if [ -n "$_BRAIN_NEW_URL" ]; then
        echo "ARTIFACTS_SYNC: artifacts repo detected: $_BRAIN_NEW_URL"
        echo "ARTIFACTS_SYNC: run 'gstack-brain-restore' to pull your cross-machine artifacts (or 'gstack-config set artifacts_sync_mode off' to dismiss forever)"
      fi
    fi
    
    if [ -d "$_GSTACK_HOME/.git" ] && [ "$_BRAIN_SYNC_MODE" != "off" ]; then
      _BRAIN_LAST_PULL_FILE="$_GSTACK_HOME/.brain-last-pull"
      _BRAIN_NOW=$(date +%s)
      _BRAIN_DO_PULL=1
      if [ -f "$_BRAIN_LAST_PULL_FILE" ]; then
        _BRAIN_LAST=$(cat "$_BRAIN_LAST_PULL_FILE" 2>/dev/null || echo 0)
        case "$_BRAIN_LAST" in ''|*[!0-9]*) _BRAIN_LAST=0 ;; esac
        _BRAIN_AGE=$(( _BRAIN_NOW - _BRAIN_LAST ))
        [ "$_BRAIN_AGE" -lt 86400 ] && _BRAIN_DO_PULL=0
      fi
      if [ "$_BRAIN_DO_PULL" = "1" ]; then
        ( cd "$_GSTACK_HOME" && git fetch origin >/dev/null 2>&1 && git merge --ff-only "origin/$(git rev-parse --abbrev-ref HEAD)" >/dev/null 2>&1 ) || true
        echo "$_BRAIN_NOW" > "$_BRAIN_LAST_PULL_FILE"
      fi
      "$_BRAIN_SYNC_BIN" --once 2>/dev/null || true
    fi
    
    if [ "$_GBRAIN_MCP_MODE" = "remote-http" ]; then
      # Remote-MCP mode: local artifacts sync is a no-op (brain admin's server
      # pulls from GitHub/GitLab). Show the user this is by design, not broken.
      _GBRAIN_HOST=$(printf '%s' "${_GBRAIN_MCP_ENTRY:-}" | jq -r '.url // empty' 2>/dev/null | sed -E 's|^https?://([^/:]+).*|\1|' | head -1 | tr -cd 'A-Za-z0-9._-')
      echo "ARTIFACTS_SYNC: remote-mode (managed by brain server ${_GBRAIN_HOST:-remote})"
    elif [ -d "$_GSTACK_HOME/.git" ] && [ "$_BRAIN_SYNC_MODE" != "off" ]; then
      _BRAIN_QUEUE_DEPTH=0
      # Spool-dir queue (one file per record); legacy .brain-queue.jsonl lines are
      # counted too until the drain migrates them.
      [ -d "$_GSTACK_HOME/.brain-queue.d" ] && _BRAIN_QUEUE_DEPTH=$(find "$_GSTACK_HOME/.brain-queue.d" -maxdepth 1 -name '*.json' 2>/dev/null | wc -l | tr -d ' ')
      [ -f "$_GSTACK_HOME/.brain-queue.jsonl" ] && _BRAIN_QUEUE_DEPTH=$(( _BRAIN_QUEUE_DEPTH + $(wc -l < "$_GSTACK_HOME/.brain-queue.jsonl" | tr -d ' ') ))
      [ -f "$_GSTACK_HOME/.brain-queue.jsonl.migrating" ] && _BRAIN_QUEUE_DEPTH=$(( _BRAIN_QUEUE_DEPTH + $(wc -l < "$_GSTACK_HOME/.brain-queue.jsonl.migrating" | tr -d ' ') ))
      _BRAIN_LAST_PUSH="never"
      [ -f "$_GSTACK_HOME/.brain-last-push" ] && _BRAIN_LAST_PUSH=$(cat "$_GSTACK_HOME/.brain-last-push" 2>/dev/null || echo never)
      echo "ARTIFACTS_SYNC: mode=$_BRAIN_SYNC_MODE | last_push=$_BRAIN_LAST_PUSH | queue=$_BRAIN_QUEUE_DEPTH"
    else
      echo "ARTIFACTS_SYNC: off"
    fi
    

    Privacy stop-gate: if output shows ARTIFACTS_SYNC: off, artifacts_sync_mode_prompted is false, and gbrain is on PATH or gbrain doctor --fast --json works, ask once:

    gstack can publish your artifacts (CEO plans, designs, reports) to a private GitHub repo that GBrain indexes across machines. How much should sync?

    Options:

    • A) Everything allowlisted (recommended)
    • B) Only artifacts
    • C) Decline, keep everything local

    After answer:

    # Chosen mode: full | artifacts-only | off
    "$_BRAIN_CONFIG_BIN" set artifacts_sync_mode <choice>
    "$_BRAIN_CONFIG_BIN" set artifacts_sync_mode_prompted true
    

    If A/B and ~/.gstack/.git is missing, ask whether to run gstack-artifacts-init. Do not block the skill.

    At skill END before telemetry:

    "$HOME/.claude/skills/gstack/bin/gstack-brain-sync" --discover-new 2>/dev/null || true
    "$HOME/.claude/skills/gstack/bin/gstack-brain-sync" --once 2>/dev/null || true
    

    Model-Specific Behavioral Patch (claude)

    The following nudges are tuned for the claude model family. They are subordinate to skill workflow, STOP points, AskUserQuestion gates, plan-mode safety, and /ship review gates. If a nudge below conflicts with skill instructions, the skill wins. Treat these as preferences, not rules.

    Todo-list discipline. When working through a multi-step plan, mark each task complete individually as you finish it. Do not batch-complete at the end. If a task turns out to be unnecessary, mark it skipped with a one-line reason.

    Think before heavy actions. For complex operations (refactors, migrations, non-trivial new features), briefly state your approach before executing. This lets the user course-correct cheaply instead of mid-flight.

    Dedicated tools over Bash. Prefer Read, Edit, Write, Glob, Grep over shell equivalents (cat, sed, find, grep). The dedicated tools are cheaper and clearer.

    Voice

    Direct, concrete, builder-to-builder. Name the file, function, command, and user-visible impact. No filler.

    No em dashes. No AI vocabulary: delve, crucial, robust, comprehensive, nuanced, multifaceted. Never corporate or academic. Short paragraphs. End with what to do.

    The user has context you do not. Cross-model agreement is a recommendation, not a decision. The user decides.

    Completion Status Protocol

    When completing a skill workflow, report status using one of:

    • DONE — completed with evidence.
    • DONE_WITH_CONCERNS — completed, but list concerns.
    • BLOCKED — cannot proceed; state blocker and what was tried.
    • NEEDS_CONTEXT — missing info; state exactly what is needed.

    Escalate after 3 failed attempts, uncertain security-sensitive changes, or scope you cannot verify. Format: STATUS, REASON, ATTEMPTED, RECOMMENDATION.

    Operational Self-Improvement

    Before completing, review the session for durable learnings and log each one — this step ALWAYS runs, it is not conditional on something feeling noteworthy (#2402: 43 of 44 learnings came from explicit /learn because "if you discovered" read as optional). A durable learning is a project quirk, command fix, pitfall, or pattern that would save 5+ minutes in a future session. If the review genuinely surfaces none, state "No durable learnings this session" in your completion summary — an explicit empty result, not a skipped step.

    ~/.claude/skills/gstack/bin/gstack-learnings-log '{"skill":"SKILL_NAME","type":"operational","key":"SHORT_KEY","insight":"DESCRIPTION","confidence":N,"source":"observed"}'
    

    Do not log obvious facts or one-time transient errors.

    Telemetry (run last)

    After workflow completion, log telemetry. Use skill name: from frontmatter. OUTCOME is success/error/abort/unknown.

    PLAN MODE EXCEPTION — ALWAYS RUN: This command writes telemetry to ~/.gstack/analytics/, matching preamble analytics writes.

    Run this bash:

    _TEL_END=$(date +%s)
    _TEL_DUR=$(( _TEL_END - _TEL_START ))
    rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true
    # Session timeline: record skill completion (local-only, never sent anywhere)
    ~/.claude/skills/gstack/bin/gstack-timeline-log '{"skill":"SKILL_NAME","event":"completed","branch":"'$(git branch --show-current 2>/dev/null || echo unknown)'","outcome":"OUTCOME","duration_s":"'"$_TEL_DUR"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null || true
    # Local analytics (gated on telemetry setting)
    if [ "$_TEL" != "off" ]; then
    echo '{"skill":"SKILL_NAME","duration_s":"'"$_TEL_DUR"'","outcome":"OUTCOME","browse":"USED_BROWSE","session":"'"$_SESSION_ID"'","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
    fi
    # Remote telemetry (opt-in, requires binary)
    if [ "$_TEL" != "off" ] && [ -x ~/.claude/skills/gstack/bin/gstack-telemetry-log ]; then
      ~/.claude/skills/gstack/bin/gstack-telemetry-log \
        --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \
        --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" \
        --error-message "ERROR_MESSAGE" --failed-step "FAILED_STEP" 2>/dev/null &
    fi
    

    Replace SKILL_NAME, OUTCOME, and USED_BROWSE before running. Replace ERROR_MESSAGE with a short description of the error (if outcome is error, otherwise use empty string ""), and FAILED_STEP with the step name or number where the failure occurred (if outcome is error, otherwise use empty string "").

    Plan Status Footer

    Skills that run plan reviews (/plan-*-review, /codex review) include the EXIT PLAN MODE GATE blocking checklist at the end of the skill, which verifies the plan file ends with ## GSTACK REVIEW REPORT before ExitPlanMode is called. Skills that don't run plan reviews (operational skills like /ship, /qa, /review) typically don't operate in plan mode and have no review report to verify; this footer is a no-op for them. Writing the plan file is the one edit allowed in plan mode.

    /open-gstack-browser — Launch GStack Browser

    Launch GStack Browser — AI-controlled Chromium with the sidebar extension, anti-bot stealth, and custom branding. You see every action in real time.

    SETUP (run this check BEFORE any browse command)

    _ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
    B=""
    [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse"
    [ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse"
    if [ -x "$B" ]; then
      echo "READY: $B"
    else
      echo "NEEDS_SETUP"
    fi
    

    If NEEDS_SETUP:

    1. Tell the user: "gstack browse needs a one-time build (~10 seconds). OK to proceed?" Then STOP and wait.
    2. Run: cd <SKILL_DIR> && ./setup
    3. If bun is not installed:
      if ! command -v bun >/dev/null 2>&1; then
        BUN_VERSION="1.3.10"
        BUN_INSTALL_SHA="bab8acfb046aac8c72407bdcce903957665d655d7acaa3e11c7c4616beae68dd"
        tmpfile=$(mktemp)
        curl -fsSL "https://bun.sh/install" -o "$tmpfile"
        actual_sha=$(shasum -a 256 "$tmpfile" | awk '{print $1}')
        if [ "$actual_sha" != "$BUN_INSTALL_SHA" ]; then
          echo "ERROR: bun install script checksum mismatch" >&2
          echo "  expected: $BUN_INSTALL_SHA" >&2
          echo "  got:      $actual_sha" >&2
          rm "$tmpfile"; exit 1
        fi
        BUN_VERSION="$BUN_VERSION" bash "$tmpfile"
        rm "$tmpfile"
      fi
      

    Step 0: Pre-flight cleanup

    Before connecting, kill any stale browse servers and clean up lock files that may have persisted from a crash. This prevents "already connected" false positives and Chromium profile lock conflicts.

    # Kill any existing browse server
    if [ -f "$(git rev-parse --show-toplevel 2>/dev/null)/.gstack/browse.json" ]; then
      _OLD_PID=$(cat "$(git rev-parse --show-toplevel)/.gstack/browse.json" 2>/dev/null | grep -o '"pid":[0-9]*' | grep -o '[0-9]*')
      [ -n "$_OLD_PID" ] && kill "$_OLD_PID" 2>/dev/null || true
      sleep 1
      [ -n "$_OLD_PID" ] && kill -9 "$_OLD_PID" 2>/dev/null || true
      rm -f "$(git rev-parse --show-toplevel)/.gstack/browse.json"
    fi
    # Clean Chromium profile locks (can persist after crashes)
    _PROFILE_DIR="$HOME/.gstack/chromium-profile"
    for _LF in SingletonLock SingletonSocket SingletonCookie; do
      rm -f "$_PROFILE_DIR/$_LF" 2>/dev/null || true
    done
    echo "Pre-flight cleanup done"
    

    Step 1: Connect

    $B connect
    

    This launches GStack Browser (rebranded Chromium) in headed mode with:

    • A visible window you can watch (not your regular Chrome — it stays untouched)
    • The gstack sidebar extension auto-loaded via launchPersistentContext
    • Anti-bot stealth patches (sites like Google and NYTimes work without captchas)
    • Custom user agent and GStack Browser branding in Dock/menu bar
    • A sidebar agent process for chat commands

    The connect command auto-discovers the extension from the gstack install directory. It always uses port 34567 so the extension can auto-connect.

    After connecting, print the full output to the user. Confirm you see Mode: headed in the output.

    If the output shows an error or the mode is not headed, run $B status and share the output with the user before proceeding.

    Step 2: Verify

    $B status
    

    Confirm the output shows Mode: headed. Read the port from the state file:

    cat "$(git rev-parse --show-toplevel 2>/dev/null)/.gstack/browse.json" 2>/dev/null | grep -o '"port":[0-9]*' | grep -o '[0-9]*'
    

    The port should be 34567. If it's different, note it — the user may need it for the Side Panel.

    Also find the extension path so you can help the user if they need to load it manually:

    _EXT_PATH=""
    _ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
    [ -n "$_ROOT" ] && [ -f "$_ROOT/.claude/skills/gstack/extension/manifest.json" ] && _EXT_PATH="$_ROOT/.claude/skills/gstack/extension"
    [ -z "$_EXT_PATH" ] && [ -f "$HOME/.claude/skills/gstack/extension/manifest.json" ] && _EXT_PATH="$HOME/.claude/skills/gstack/extension"
    echo "EXTENSION_PATH: ${_EXT_PATH:-NOT FOUND}"
    

    Step 3: Guide the user to the Side Panel

    Use AskUserQuestion:

    Chrome is launched with gstack control. You should see Playwright's Chromium (not your regular Chrome) with a golden shimmer line at the top of the page.

    The Side Panel extension should be auto-loaded. To open it:

    1. Look for the puzzle piece icon (Extensions) in the toolbar — it may already show the gstack icon if the extension loaded successfully
    2. Click the puzzle piece → find gstack browse → click the pin icon
    3. Click the pinned gstack icon in the toolbar
    4. The Side Panel should open on the right showing a live activity feed

    Port: 34567 (auto-detected — the extension connects automatically in the Playwright-controlled Chrome).

    Options:

    • A) I can see the Side Panel — let's go!
    • B) I can see Chrome but can't find the extension
    • C) Something went wrong

    If B: Tell the user:

    The extension is loaded into Playwright's Chromium at launch time, but sometimes it doesn't appear immediately. Try these steps:

    1. Type chrome://extensions in the address bar
    2. Look for "gstack browse" — it should be listed and enabled
    3. If it's there but not pinned, go back to any page, click the puzzle piece icon, and pin it
    4. If it's NOT listed at all, click "Load unpacked" and navigate to:
      • Press Cmd+Shift+G in the file picker dialog
      • Paste this path: {EXTENSION_PATH} (use the path from Step 2)
      • Click Select

    After loading, pin it and click the icon to open the Side Panel.

    If the Side Panel badge stays gray (disconnected), click the gstack icon and enter port 34567 manually.

    If C:

    1. Run $B status and show the output
    2. If the server is not healthy, re-run Step 0 cleanup + Step 1 connect
    3. If the server IS healthy but the browser isn't visible, try $B focus
    4. If that fails, ask the user what they see (error message, blank screen, etc.)

    Step 4: Demo

    After the user confirms the Side Panel is working, run a quick demo:

    $B goto https://news.ycombinator.com
    

    Wait 2 seconds, then:

    $B snapshot -i
    

    Tell the user: "Check the Side Panel — you should see the goto and snapshot commands appear in the activity feed. Every command Claude runs shows up here in real time."

    Step 5: Sidebar chat

    After the activity feed demo, tell the user about the sidebar chat:

    The Side Panel also has a chat tab. Try typing a message like "take a snapshot and describe this page." A sidebar agent (a child Claude instance) executes your request in the browser — you'll see the commands appear in the activity feed as they happen.

    The sidebar agent can navigate pages, click buttons, fill forms, and read content. Each task gets up to 5 minutes. It runs in an isolated session, so it won't interfere with this Claude Code window.

    Step 6: What's next

    Tell the user:

    You're all set! Here's what you can do with the connected Chrome:

    Watch Claude work in real time:

    • Run any gstack skill (/qa, /design-review, /benchmark) and watch every action happen in the visible Chrome window + Side Panel feed
    • No cookie import needed — the Playwright browser shares its own session

    Control the browser directly:

    • Sidebar chat — type natural language in the Side Panel and the sidebar agent executes it (e.g., "fill in the login form and submit")
    • Browse commands$B goto <url>, $B click <sel>, $B fill <sel> <val>, $B snapshot -i — all visible in Chrome + Side Panel

    Window management:

    • $B focus — bring Chrome to the foreground anytime
    • $B disconnect — close headed Chrome and return to headless mode

    What skills look like in headed mode:

    • /qa runs its full test suite in the visible browser — you see every page load, every click, every assertion
    • /design-review takes screenshots in the real browser — same pixels you see
    • /benchmark measures performance in the headed browser

    Then proceed with whatever the user asked to do. If they didn't specify a task, ask what they'd like to test or browse.

    Reproducido de garrytan/gstack bajo licencia MIT. Leer esta página en markdown.

    Archivos

    2 archivos en el paquete. Solo se lee SKILL.md al activarse — las referencias se cargan si el skill decide que las necesita.

    Antes de instalar

    Requiere el binario `browse` (compilable con `./setup`, que necesita `bun`) y git para detectar la raíz del repo.

    Necesita en el PATH:awkgitjqsed

    Variables de entorno:BUN_INSTALL_SHABUN_VERSIONCLAUDE_PLAN_FILECONDUCTOR_PORTCONDUCTOR_WORKSPACE_PATHGSTACK_HOMEGSTACK_PLAN_MODEGSTACK_PLAN_MODE_FORCEOPENCLAW_SESSIONPPIDREPO_MODESLUG

    Detalles

    Creador
    garrytan
    Licencia
    MIT
    Recursos incluidos
    Incluye scripts o referencias
    Repositorio
    garrytan/gstack
    Código fuente
    Ver SKILL.md

    Más de garrytan/gstack

    Este repo incluye 59 skills. Si instalas uno, normalmente ya tienes los demás.

    Browse

    129k

    Navegador headless rápido para QA testing y dogfooding de sitios (gstack).

    Costo de contexto al activarse
    14.8k tok
    Tamaño del paquete
    237 archivos
    Última actualización
    hace 7 horas
    Permisos
    testing qa

    Ship

    129k

    Flujo de ship: detecta y fusiona la rama base, corre tests, revisa el diff, sube VERSION, actualiza CHANGELOG, hace commit, push y crea el PR (gstack).

    Costo de contexto al activarse
    22.8k tok
    Tamaño del paquete
    21 archivos
    Última actualización
    anteayer
    Permisos
    devops infraestructura

    Ios Qa

    129k

    QA en dispositivo iOS real para apps SwiftUI, con bucle de agente guiado por visión sobre USB (gstack).

    Costo de contexto al activarse
    15.4k tok
    Tamaño del paquete
    38 archivos
    Última actualización
    anteayer
    Permisos
    testing qa

    Revisión de planes con ojo de diseñador — interactiva, al estilo de las revisiones de CEO e Ingeniería. (gstack)

    Costo de contexto al activarse
    22.8k tok
    Tamaño del paquete
    5 archivos
    Última actualización
    anteayer
    Permisos
    diseno ui

    Revisión de plan en modo gerente de ingeniería: arquitectura, flujo de datos, diagramas, casos límite, cobertura de pruebas y rendimiento. (gstack)

    Costo de contexto al activarse
    17.9k tok
    Tamaño del paquete
    5 archivos
    Última actualización
    anteayer
    Permisos
    herramientas desarrollo

    Actualización de documentación posterior al ship (gstack).

    Costo de contexto al activarse
    14.4k tok
    Tamaño del paquete
    5 archivos
    Última actualización
    anteayer
    Permisos
    documentos

    Skills relacionados

    Úsalo cuando la implementación esté completa, todos los tests pasen, y necesites decidir cómo integrar el trabajo.

    Costo de contexto al activarse
    1.9k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 9 días
    herramientas desarrollo

    Úsalo al empezar trabajo de feature que necesita aislamiento del workspace actual, o antes de ejecutar planes de implementación: asegura un workspace aislado vía herramientas nativas o fallback a git worktree.

    Costo de contexto al activarse
    1.7k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    herramientas desarrollo

    Úsala al crear nuevas skills, editar skills existentes o verificar que funcionan antes de desplegarlas.

    Costo de contexto al activarse
    6.6k tok
    Tamaño del paquete
    7 archivos
    Última actualización
    hace 9 días
    herramientas desarrollo