browse

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
<!-- AUTO-GENERATED from SKILL.md.tmpl — do not edit directly --> <!-- Regenerate: bun run gen:skill-docs -->
<!-- 由 SKILL.md.tmpl 自动生成 — 请勿直接编辑 --> <!-- 重新生成:bun run gen:skill-docs -->

Preamble (run first)

前置步骤(首先运行)

bash
_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 -delete 2>/dev/null || true
_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true)
_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
echo "BRANCH: $_BRANCH"
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
JUST_UPGRADED <from> <to>
: tell user "Running gstack v{to} (just updated!)" and continue.
bash
_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 -delete 2>/dev/null || true
_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true)
_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
echo "BRANCH: $_BRANCH"
如果输出显示
UPGRADE_AVAILABLE <old> <new>
:请阅读
~/.claude/skills/gstack/gstack-upgrade/SKILL.md
并遵循“内联升级流程”(如果已配置则自动升级,否则向用户提供4个选项,若用户拒绝则记录 snooze 状态)。如果显示
JUST_UPGRADED <from> <to>
:告知用户“正在运行 gstack v{to}(刚刚完成更新!)”并继续后续操作。

AskUserQuestion Format

询问用户问题的格式

ALWAYS follow this structure for every AskUserQuestion call:
  1. Re-ground: State the project, the current branch (use the
    _BRANCH
    value printed by the preamble — NOT any branch from conversation history or gitStatus), and the current plan/task. (1-2 sentences)
  2. Simplify: Explain the problem in plain English a smart 16-year-old could follow. No raw function names, no internal jargon, no implementation details. Use concrete examples and analogies. Say what it DOES, not what it's called.
  3. Recommend:
    RECOMMENDATION: Choose [X] because [one-line reason]
  4. Options: Lettered options:
    A) ... B) ... C) ...
Assume the user hasn't looked at this window in 20 minutes and doesn't have the code open. If you'd need to read the source to understand your own explanation, it's too complex.
Per-skill instructions may add additional formatting rules on top of this baseline.
每次调用AskUserQuestion时必须遵循以下结构:
  1. 重述背景: 说明项目、当前分支(使用前置步骤输出的
    _BRANCH
    值 — 不要使用对话历史或gitStatus中的分支),以及当前计划/任务。(1-2句话)
  2. 简化说明: 用通俗易懂的语言解释问题,确保一个聪明的16岁学生能理解。不要使用原始函数名、内部术语或实现细节。使用具体示例和类比。说明功能用途,而非技术名称。
  3. 推荐选项:
    RECOMMENDATION: 选择[X],因为[一句话理由]
  4. 选项列表: 带字母标识的选项:
    A) ... B) ... C) ...
假设用户已有20分钟未查看此窗口且未打开代码。如果你的解释需要阅读源码才能理解,说明过于复杂。
特定技能的说明可能会在此基础格式上添加额外的格式规则。

Contributor Mode

贡献者模式

If
_CONTRIB
is
true
: you are in contributor mode. You're a gstack user who also helps make it better.
At the end of each major workflow step (not after every single command), reflect on the gstack tooling you used. Rate your experience 0 to 10. If it wasn't a 10, think about why. If there is an obvious, actionable bug OR an insightful, interesting thing that could have been done better by gstack code or skill markdown — file a field report. Maybe our contributor will help make us better!
Calibration — this is the bar: For example,
$B js "await fetch(...)"
used to fail with
SyntaxError: await is only valid in async functions
because gstack didn't wrap expressions in async context. Small, but the input was reasonable and gstack should have handled it — that's the kind of thing worth filing. Things less consequential than this, ignore.
NOT worth filing: user's app bugs, network errors to user's URL, auth failures on user's site, user's own JS logic bugs.
To file: write
~/.gstack/contributor-logs/{slug}.md
with all sections below (do not truncate — include every section through the Date/Version footer):
undefined
如果
_CONTRIB
true
:你处于贡献者模式。你是一名gstack用户,同时也参与工具改进。
在每个主要工作流步骤结束时(并非每个命令后),回顾你使用的gstack工具。为你的体验打分(0-10分)。如果未达到10分,思考原因。如果存在明显可修复的Bug,或者gstack的代码或技能文档有明确可优化的空间 — 提交一份现场报告。我们的贡献者可能会帮助改进工具!
校准标准: 例如,
$B js "await fetch(...)"
曾因gstack未将表达式包裹在async上下文中而报错
SyntaxError: await is only valid in async functions
。这是一个小问题,但输入是合理的,gstack本应处理这种情况 — 这类问题值得提交报告。比这更轻微的问题可以忽略。
无需提交的情况: 用户应用程序的Bug、用户URL的网络错误、用户网站的认证失败、用户自身的JS逻辑Bug。
提交报告: 写入
~/.gstack/contributor-logs/{slug}.md
,包含以下所有部分(请勿截断 — 包含至日期/版本页脚的所有部分):
undefined

{Title}

{标题}

Hey gstack team — ran into this while using /{skill-name}:
What I was trying to do: {what the user/agent was attempting} What happened instead: {what actually happened} My rating: {0-10} — {one sentence on why it wasn't a 10}
嗨,gstack团队 — 在使用/{技能名称}时遇到了这个问题:
我尝试做什么: {用户/Agent的操作意图} 实际发生了什么: {实际结果} 我的评分: {0-10} — {一句话说明未打10分的原因}

Steps to reproduce

复现步骤

  1. {step}
  1. {步骤}

Raw output

原始输出

{paste the actual error or unexpected output here}
{粘贴实际错误或意外输出}

What would make this a 10

如何达到10分体验

{one sentence: what gstack should have done differently}
Date: {YYYY-MM-DD} | Version: {gstack version} | Skill: /{skill}

Slug: lowercase, hyphens, max 60 chars (e.g. `browse-js-no-await`). Skip if file already exists. Max 3 reports per session. File inline and continue — don't stop the workflow. Tell user: "Filed gstack field report: {title}"
{一句话:gstack本应如何改进}
日期: {YYYY-MM-DD} | 版本: {gstack版本} | 技能: /{技能名}

Slug:小写,用连字符分隔,最多60个字符(例如`browse-js-no-await`)。如果文件已存在则跳过。每个会话最多提交3份报告。直接在当前流程中提交并继续 — 不要中断工作流。告知用户:“已提交gstack现场报告:{标题}”

browse: QA Testing & Dogfooding

browse: QA测试与内部试用

Persistent headless Chromium. First call auto-starts (~3s), then ~100ms per command. State persists between calls (cookies, tabs, login sessions).
持久化无头Chromium浏览器。首次调用会自动启动(约3秒),后续每个命令耗时约100毫秒。调用之间会保留状态(Cookie、标签页、登录会话)。

SETUP (run this check BEFORE any browse command)

安装检查(运行任何browse命令前执行)

bash
_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=~/.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:
    curl -fsSL https://bun.sh/install | bash
bash
_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=~/.claude/skills/gstack/browse/dist/browse
if [ -x "$B" ]; then
  echo "READY: $B"
else
  echo "NEEDS_SETUP"
fi
如果输出为
NEEDS_SETUP
  1. 告知用户:“gstack browse需要一次性构建(约10秒)。是否继续?”然后等待用户回复。
  2. 运行:
    cd <SKILL_DIR> && ./setup
  3. 如果未安装bun:
    curl -fsSL https://bun.sh/install | bash

Core QA Patterns

核心QA测试模式

1. Verify a page loads correctly

1. 验证页面是否正确加载

bash
$B goto https://yourapp.com
$B text                          # content loads?
$B console                       # JS errors?
$B network                       # failed requests?
$B is visible ".main-content"    # key elements present?
bash
$B goto https://yourapp.com
$B text                          # 内容是否加载?
$B console                       # 是否有JS错误?
$B network                       # 是否有请求失败?
$B is visible ".main-content"    # 关键元素是否存在?

2. Test a user flow

2. 测试用户流程

bash
$B goto https://app.com/login
$B snapshot -i                   # see all interactive elements
$B fill @e3 "user@test.com"
$B fill @e4 "password"
$B click @e5                     # submit
$B snapshot -D                   # diff: what changed after submit?
$B is visible ".dashboard"       # success state present?
bash
$B goto https://app.com/login
$B snapshot -i                   # 查看所有可交互元素
$B fill @e3 "user@test.com"
$B fill @e4 "password"
$B click @e5                     # 提交
$B snapshot -D                   # 对比:提交后页面有何变化?
$B is visible ".dashboard"       # 是否显示成功状态?

3. Verify an action worked

3. 验证操作是否生效

bash
$B snapshot                      # baseline
$B click @e3                     # do something
$B snapshot -D                   # unified diff shows exactly what changed
bash
$B snapshot                      # 生成基线快照
$B click @e3                     # 执行操作
$B snapshot -D                   # 统一差异对比显示具体变化

4. Visual evidence for bug reports

4. 为Bug报告提供可视化证据

bash
$B snapshot -i -a -o /tmp/annotated.png   # labeled screenshot
$B screenshot /tmp/bug.png                # plain screenshot
$B console                                # error log
bash
$B snapshot -i -a -o /tmp/annotated.png   # 带标注的截图
$B screenshot /tmp/bug.png                # 普通截图
$B console                                # 错误日志

5. Find all clickable elements (including non-ARIA)

5. 查找所有可点击元素(包括非ARIA元素)

bash
$B snapshot -C                   # finds divs with cursor:pointer, onclick, tabindex
$B click @c1                     # interact with them
bash
$B snapshot -C                   # 查找带有cursor:pointer、onclick、tabindex的div元素
$B click @c1                     # 与元素交互

6. Assert element states

6. 断言元素状态

bash
$B is visible ".modal"
$B is enabled "#submit-btn"
$B is disabled "#submit-btn"
$B is checked "#agree-checkbox"
$B is editable "#name-field"
$B is focused "#search-input"
$B js "document.body.textContent.includes('Success')"
bash
$B is visible ".modal"
$B is enabled "#submit-btn"
$B is disabled "#submit-btn"
$B is checked "#agree-checkbox"
$B is editable "#name-field"
$B is focused "#search-input"
$B js "document.body.textContent.includes('Success')"

7. Test responsive layouts

7. 测试响应式布局

bash
$B responsive /tmp/layout        # mobile + tablet + desktop screenshots
$B viewport 375x812              # or set specific viewport
$B screenshot /tmp/mobile.png
bash
$B responsive /tmp/layout        # 生成移动端、平板端、桌面端截图
$B viewport 375x812              # 或设置特定视口尺寸
$B screenshot /tmp/mobile.png

8. Test file uploads

8. 测试文件上传

bash
$B upload "#file-input" /path/to/file.pdf
$B is visible ".upload-success"
bash
$B upload "#file-input" /path/to/file.pdf
$B is visible ".upload-success"

9. Test dialogs

9. 测试对话框

bash
$B dialog-accept "yes"           # set up handler
$B click "#delete-button"        # trigger dialog
$B dialog                        # see what appeared
$B snapshot -D                   # verify deletion happened
bash
$B dialog-accept "yes"           # 设置对话框处理程序
$B click "#delete-button"        # 触发对话框
$B dialog                        # 查看弹出的对话框内容
$B snapshot -D                   # 验证删除操作是否完成

10. Compare environments

10. 对比不同环境

bash
$B diff https://staging.app.com https://prod.app.com
bash
$B diff https://staging.app.com https://prod.app.com

Snapshot Flags

Snapshot参数

The snapshot is your primary tool for understanding and interacting with pages.
-i        --interactive           Interactive elements only (buttons, links, inputs) with @e refs
-c        --compact               Compact (no empty structural nodes)
-d <N>    --depth                 Limit tree depth (0 = root only, default: unlimited)
-s <sel>  --selector              Scope to CSS selector
-D        --diff                  Unified diff against previous snapshot (first call stores baseline)
-a        --annotate              Annotated screenshot with red overlay boxes and ref labels
-o <path> --output                Output path for annotated screenshot (default: /tmp/browse-annotated.png)
-C        --cursor-interactive    Cursor-interactive elements (@c refs — divs with pointer, onclick)
All flags can be combined freely.
-o
only applies when
-a
is also used. Example:
$B snapshot -i -a -C -o /tmp/annotated.png
Ref numbering: @e refs are assigned sequentially (@e1, @e2, ...) in tree order. @c refs from
-C
are numbered separately (@c1, @c2, ...).
After snapshot, use @refs as selectors in any command:
bash
$B click @e3       $B fill @e4 "value"     $B hover @e1
$B html @e2        $B css @e5 "color"      $B attrs @e6
$B click @c1       # cursor-interactive ref (from -C)
Output format: indented accessibility tree with @ref IDs, one element per line.
  @e1 [heading] "Welcome" [level=1]
  @e2 [textbox] "Email"
  @e3 [button] "Submit"
Refs are invalidated on navigation — run
snapshot
again after
goto
.
Snapshot是你理解和与页面交互的主要工具。
-i        --interactive           仅显示可交互元素(按钮、链接、输入框),并分配@e引用标识
-c        --compact               紧凑模式(不显示空结构节点)
-d <N>    --depth                 限制树深度(0=仅根节点,默认:无限制)
-s <sel>  --selector              限定CSS选择器范围
-D        --diff                  与上一次快照进行统一差异对比(首次调用会存储基线)
-a        --annotate              生成带红色覆盖框和引用标识的标注截图
-o <path> --output                标注截图的输出路径(默认:/tmp/browse-annotated.png)
-C        --cursor-interactive    显示光标可交互元素(@c引用标识 — 带有pointer、onclick的div)
所有参数可自由组合。
-o
仅在同时使用
-a
时生效。 示例:
$B snapshot -i -a -C -o /tmp/annotated.png
引用编号规则: @e引用按树顺序依次分配(@e1、@e2...)。
-C
参数生成的@c引用单独编号(@c1、@c2...)。
生成快照后,可在任何命令中使用@引用作为选择器:
bash
$B click @e3       $B fill @e4 "value"     $B hover @e1
$B html @e2        $B css @e5 "color"      $B attrs @e6
$B click @c1       # 光标可交互元素引用(来自-C参数)
输出格式: 带缩进的无障碍树结构,包含@引用ID,每行一个元素。
  @e1 [heading] "Welcome" [level=1]
  @e2 [textbox] "Email"
  @e3 [button] "Submit"
导航后引用会失效 — 执行
goto
后需重新运行
snapshot

Full Command List

完整命令列表

Navigation

导航

CommandDescription
back
History back
forward
History forward
goto <url>
Navigate to URL
reload
Reload page
url
Print current URL
命令描述
back
返回历史页面
forward
前进到历史页面
goto <url>
导航到指定URL
reload
重新加载页面
url
打印当前URL

Reading

页面读取

CommandDescription
accessibility
Full ARIA tree
forms
Form fields as JSON
html [selector]
innerHTML of selector (throws if not found), or full page HTML if no selector given
links
All links as "text → href"
text
Cleaned page text
命令描述
accessibility
完整ARIA树
forms
以JSON格式显示表单字段
html [selector]
选择器对应的innerHTML(未找到则抛出错误),无选择器时返回完整页面HTML
links
所有链接,格式为“文本 → href”
text
清理后的页面文本

Interaction

交互操作

CommandDescription
click <sel>
Click element
cookie <name>=<value>
Set cookie on current page domain
cookie-import <json>
Import cookies from JSON file
cookie-import-browser [browser] [--domain d]
Import cookies from Comet, Chrome, Arc, Brave, or Edge (opens picker, or use --domain for direct import)
dialog-accept [text]
Auto-accept next alert/confirm/prompt. Optional text is sent as the prompt response
dialog-dismiss
Auto-dismiss next dialog
fill <sel> <val>
Fill input
header <name>:<value>
Set custom request header (colon-separated, sensitive values auto-redacted)
hover <sel>
Hover element
press <key>
Press key — Enter, Tab, Escape, ArrowUp/Down/Left/Right, Backspace, Delete, Home, End, PageUp, PageDown, or modifiers like Shift+Enter
scroll [sel]
Scroll element into view, or scroll to page bottom if no selector
select <sel> <val>
Select dropdown option by value, label, or visible text
type <text>
Type into focused element
upload <sel> <file> [file2...]
Upload file(s)
useragent <string>
Set user agent
viewport <WxH>
Set viewport size
`wait <sel--networkidle
命令描述
click <sel>
点击元素
cookie <name>=<value>
在当前页面域名设置Cookie
cookie-import <json>
从JSON文件导入Cookie
cookie-import-browser [browser] [--domain d]
从Comet、Chrome、Arc、Brave或Edge浏览器导入Cookie(打开选择器,或使用--domain直接导入)
dialog-accept [text]
自动接受下一个警告/确认/提示对话框。可选文本作为提示框的响应内容
dialog-dismiss
自动关闭下一个对话框
fill <sel> <val>
填充输入框
header <name>:<value>
设置自定义请求头(冒号分隔,敏感值会自动脱敏)
hover <sel>
悬停在元素上
press <key>
按键 — Enter、Tab、Escape、ArrowUp/Down/Left/Right、Backspace、Delete、Home、End、PageUp、PageDown,或组合键如Shift+Enter
scroll [sel]
将元素滚动到视图中,无选择器时滚动到页面底部
select <sel> <val>
按值、标签或可见文本选择下拉选项
type <text>
在聚焦元素中输入文本
upload <sel> <file> [file2...]
上传文件(可多个)
useragent <string>
设置用户代理
viewport <WxH>
设置视口尺寸
`wait <sel--networkidle

Inspection

检查工具

CommandDescription
`attrs <sel@ref>`
`console [--clear--errors]`
cookies
All cookies as JSON
css <sel> <prop>
Computed CSS value
dialog [--clear]
Dialog messages
eval <file>
Run JavaScript from file and return result as string (path must be under /tmp or cwd)
is <prop> <sel>
State check (visible/hidden/enabled/disabled/checked/editable/focused)
js <expr>
Run JavaScript expression and return result as string
network [--clear]
Network requests
perf
Page load timings
storage [set k v]
Read all localStorage + sessionStorage as JSON, or set <key> <value> to write localStorage
命令描述
`attrs <sel@ref>`
`console [--clear--errors]`
cookies
以JSON格式显示所有Cookie
css <sel> <prop>
计算后的CSS属性值
dialog [--clear]
对话框消息
eval <file>
运行文件中的JavaScript并返回结果字符串(路径必须在/tmp或当前工作目录下)
is <prop> <sel>
状态检查(visible/hidden/enabled/disabled/checked/editable/focused)
js <expr>
运行JavaScript表达式并返回结果字符串
network [--clear]
网络请求记录
perf
页面加载时间统计
storage [set k v]
读取所有localStorage和sessionStorage(JSON格式),或使用set <key> <value>写入localStorage

Visual

可视化操作

CommandDescription
diff <url1> <url2>
Text diff between pages
pdf [path]
Save as PDF
responsive [prefix]
Screenshots at mobile (375x812), tablet (768x1024), desktop (1280x720). Saves as {prefix}-mobile.png etc.
`screenshot [--viewport] [--clip x,y,w,h] [selector@ref] [path]`
命令描述
diff <url1> <url2>
页面文本差异对比
pdf [path]
保存为PDF
responsive [prefix]
生成移动端(375x812)、平板端(768x1024)、桌面端(1280x720)截图。保存为{prefix}-mobile.png等格式
`screenshot [--viewport] [--clip x,y,w,h] [selector@ref] [path]`

Snapshot

Snapshot命令

CommandDescription
snapshot [flags]
Accessibility tree with @e refs for element selection. Flags: -i interactive only, -c compact, -d N depth limit, -s sel scope, -D diff vs previous, -a annotated screenshot, -o path output, -C cursor-interactive @c refs
命令描述
snapshot [flags]
生成带@e引用标识的无障碍树,用于元素选择。参数:-i仅显示可交互元素,-c紧凑模式,-d N限制深度,-s sel限定范围,-d与上一次对比,-a生成标注截图,-o输出路径,-C显示光标可交互元素的@c引用

Meta

元命令

CommandDescription
chain
Run commands from JSON stdin. Format: [["cmd","arg1",...],...]
命令描述
chain
从标准输入的JSON运行命令。格式:[["cmd","arg1",...],...]

Tabs

标签页管理

CommandDescription
closetab [id]
Close tab
newtab [url]
Open new tab
tab <id>
Switch to tab
tabs
List open tabs
命令描述
closetab [id]
关闭标签页
newtab [url]
打开新标签页
tab <id>
切换到指定标签页
tabs
列出所有打开的标签页

Server

服务器管理

CommandDescription
restart
Restart server
status
Health check
stop
Shutdown server
命令描述
restart
重启服务器
status
健康检查
stop
关闭服务器