/ha-browser
Hope Agent browser automation — the standard `status → tabs → snapshot → act` loop, stale-ref recovery rules, and what to do when login / 2FA / captcha / camera-prompt / dialog blocks progress. Load this skill whenever you reach for the `browser` tool. Trigger on: user asks the
$ npx -y skills add shiwenwen/hope-agent --skill ha-browser --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/ha-browser
Context preview
The summary Claude sees to decide when to auto-load this skill.
Hope Agent browser automation — the standard `status → tabs → snapshot → act` loop, stale-ref recovery rules, and what to do when login / 2FA / captcha / camera-prompt / dialog blocks progress. Load this skill whenever you reach for the `browser` tool. Trigger on: user asks the
SKILL.md
ha-browser.SKILL.mdname: ha-browser
description: "Hope Agent browser automation — the standard `status → tabs → snapshot → act` loop, stale-ref recovery rules, and what to do when login / 2FA / captcha / camera-prompt / dialog blocks progress. Load this skill whenever you reach for the `browser` tool. Trigger on: user asks the agent to open / control / click / scrape / log into / verify something in a web app ('open X and click Y', '打开 X 然后点击 Y', 'log into my Gmail', 'scrape this page', 'fill out the form on X'); user reports a flow that requires real browser context (cookies, JS-rendered content, OAuth)."
version: 1.0.0
author: Hope Agent
license: MIT
allowed-tools: [browser, ask_user_question, read, job_status]
status: activeHope Agent Browser — operating loop
The `browser` tool exposes 8 high-level actions. Default backend is Hope Agent's Chrome Extension + Native Messaging Host, which can control the user's real Chrome tabs after they install the extension and native host. If the extension is unavailable, generic browsing can fall back to the managed/user_attach CDP backend, but real Chrome tab/session tasks must fail closed and ask the user to install or enable the extension.
The standard loop
Run these in order; never skip a step. Browsers are stateful — assumptions get punished.
1. browser(action="status") # never operate blindly
2. browser(action="tabs", op="list") # know what's open before opening more
3. browser(action="tabs", op="new", url=...) # only if you actually need a fresh tab
4. browser(action="snapshot", format="role") # get fresh refs
5. browser(action="act", kind=..., ref=..., ...)
6. when in doubt → re-snapshot
When the user explicitly asks for their current Chrome, an already-open tab, their logged-in session, or browser extensions/cookies from their daily Chrome, use `tabs.open_user_tabs` and `tabs.claim` first. Do not launch a managed CDP profile and pretend it is the user's Chrome.
Real Chrome access uses the normal Hope Agent tool approval flow. `tabs.open_user_tabs`, `tabs.claim`, extension numeric-id `tabs.select`, `observe.kind=downloads`, `control.download_cancel`, and `control.raw_cdp` may ask unless the session policy, AllowAlways, Smart mode, or YOLO allows them.
A typical "fill the login form" flow is:
status → tabs.list → (already on the right tab? if not, tabs.select / tabs.new)
→ navigate.go url="https://app.example.com/login"
→ snapshot format=role # capture refs
→ act kind=fill ref=<email> text="me@..."
→ act kind=fill ref=<password> text="..."
→ act kind=click ref=<submit>
→ snapshot format=role # re-snapshot after navigation
→ verify expected element existsRefs are tied to the snapshot
`ref` is **only** valid against the most recent `snapshot.role` for the active tab. The moment the page navigates, the DOM mutates (SPA route change, modal opens/closes), or you switch tab — refs are stale.
**Re-snapshot when:**
- you just called `navigate.go / .back / .forward / .reload`
- you switched tab (`tabs.select`)
- an `act` returned an error that looks like "ref not found" / "no such element" / "detached"
- the URL bar in the snapshot output differs from what you expect
- a previous `act` triggered an obvious UI change (modal, page transition, form expansion)
Stale-ref auto-recovery — what to expect
The tool tries **one** automatic recovery before bubbling up a stale-ref error: it re-snapshots, looks for an element with the same `role` and `text` (or a substring match) as the original ref, and retries with the new ref. On success the result string ends with `(ref auto-recovered)` so you know it kicked in. On failure you get the original error.
Practical rules:
- If a recovery happened, **verify the next action's prerequisites freshly** — a recovered ref means the DOM rearranged.
- If recovery fails, **resnapshot manually and re-plan** — don't keep hammering the same `act` call.
- Recovery only kicks in for `act.kind`. `navigate`, `tabs.*`, and `control.*` do not retry.
When to stop and ask the user
These five situations are **blocking** — do not guess your way through them. Call `ask_user_question` and wait.
| Signal in the snapshot or error | What you must do | | --- | --- | | Login form / email + password / "Sign in" button | Ask the user to sign in, or supply credentials via the right channel. Never type credentials you guessed. | | 2FA / OTP code prompt | Ask the user for the code (they have the device). | | CAPTCHA / "I'm not a robot" | Ask the user to solve it. Do not attempt to bypass. | | Camera / microphone / notification permission prompt | Ask the user — that's a system dialog only they can answer. | | Browser-native file picker or download confirmation | If you triggered it, `control.handle_dialog`. If it's a host-driven save dialog, ask the user. |
When you have to stop, the right call is roughly:
ask_user_question({
reason: "Browser flow requires you",
questions: [{ q: "I see a CAPTCHA on https://...; please solve it, then say 'continue'.", ... }]
})Tab discipline
Multi-tab work loses refs more than anything else. Two rules keep you sane:
1. **Name your tabs as soon as you open them.** Right after `tabs.new`, jot the `target_id` and the URL/role in your reasoning ("tab A11C = github, tab B22D = jira"). Always pass `target_id` explicitly to `tabs.select` instead of relying on "active". 2. **One snapshot per action burst per tab.** Don't snapshot tab A, switch to tab B for two ops, switch back to A, and reuse the old A refs. Re-snapshot when you come back.
Real Chrome tabs
Use the extension-backed tab lease protocol whenever the task depends on the user's real Chrome state:
status
tabs.open_user_tabs
tabs.claim target_id="<chrome-tab-id>"
snapshot / act / observe
tabs.finalize
Rules:
- `tabs.claim` takes temporary control of a real user tab. Release it with `tabs.release` o
Read more
name: ha-browser
description: "Hope Agent browser automation — the standard `status → tabs → snapshot → act` loop, stale-ref recovery rules, and what to do when login / 2FA / captcha / camera-prompt / dialog blocks progress. Load this skill whenever you reach for the `browser` tool. Trigger on: user asks the agent to open / control / click / scrape / log into / verify something in a web app ('open X and click Y', '打开 X 然后点击 Y', 'log into my Gmail', 'scrape this page', 'fill out the form on X'); user reports a flow that requires real browser context (cookies, JS-rendered content, OAuth)."
version: 1.0.0
author: Hope Agent
license: MIT
allowed-tools: [browser, ask_user_question, read, job_status]
status: activeHope Agent Browser — operating loop
The `browser` tool exposes 8 high-level actions. Default backend is Hope Agent's Chrome Extension + Native Messaging Host, which can control the user's real Chrome tabs after they install the extension and native host. If the extension is unavailable, generic browsing can fall back to the managed/user_attach CDP backend, but real Chrome tab/session tasks must fail closed and ask the user to install or enable the extension.
The standard loop
Run these in order; never skip a step. Browsers are stateful — assumptions get punished.
1. browser(action="status") # never operate blindly 2. browser(action="tabs", op="list") # know what's open before opening more 3. browser(action="tabs", op="new", url=...) # only if you actually need a fresh tab 4. browser(action="snapshot", format="role") # get fresh refs 5. browser(action="act", kind=..., ref=..., ...) 6. when in doubt → re-snapshot
When the user explicitly asks for their current Chrome, an already-open tab, their logged-in session, or browser extensions/cookies from their daily Chrome, use `tabs.open_user_tabs` and `tabs.claim` first. Do not launch a managed CDP profile and pretend it is the user's Chrome.
Real Chrome access uses the normal Hope Agent tool approval flow. `tabs.open_user_tabs`, `tabs.claim`, extension numeric-id `tabs.select`, `observe.kind=downloads`, `control.download_cancel`, and `control.raw_cdp` may ask unless the session policy, AllowAlways, Smart mode, or YOLO allows them.
A typical "fill the login form" flow is:
status → tabs.list → (already on the right tab? if not, tabs.select / tabs.new)
→ navigate.go url="https://app.example.com/login"
→ snapshot format=role # capture refs
→ act kind=fill ref=<email> text="me@..."
→ act kind=fill ref=<password> text="..."
→ act kind=click ref=<submit>
→ snapshot format=role # re-snapshot after navigation
→ verify expected element existsRefs are tied to the snapshot
`ref` is **only** valid against the most recent `snapshot.role` for the active tab. The moment the page navigates, the DOM mutates (SPA route change, modal opens/closes), or you switch tab — refs are stale.
**Re-snapshot when:**
- you just called `navigate.go / .back / .forward / .reload`
- you switched tab (`tabs.select`)
- an `act` returned an error that looks like "ref not found" / "no such element" / "detached"
- the URL bar in the snapshot output differs from what you expect
- a previous `act` triggered an obvious UI change (modal, page transition, form expansion)
Stale-ref auto-recovery — what to expect
The tool tries **one** automatic recovery before bubbling up a stale-ref error: it re-snapshots, looks for an element with the same `role` and `text` (or a substring match) as the original ref, and retries with the new ref. On success the result string ends with `(ref auto-recovered)` so you know it kicked in. On failure you get the original error.
Practical rules:
- If a recovery happened, **verify the next action's prerequisites freshly** — a recovered ref means the DOM rearranged.
- If recovery fails, **resnapshot manually and re-plan** — don't keep hammering the same `act` call.
- Recovery only kicks in for `act.kind`. `navigate`, `tabs.*`, and `control.*` do not retry.
When to stop and ask the user
These five situations are **blocking** — do not guess your way through them. Call `ask_user_question` and wait.
| Signal in the snapshot or error | What you must do | | --- | --- | | Login form / email + password / "Sign in" button | Ask the user to sign in, or supply credentials via the right channel. Never type credentials you guessed. | | 2FA / OTP code prompt | Ask the user for the code (they have the device). | | CAPTCHA / "I'm not a robot" | Ask the user to solve it. Do not attempt to bypass. | | Camera / microphone / notification permission prompt | Ask the user — that's a system dialog only they can answer. | | Browser-native file picker or download confirmation | If you triggered it, `control.handle_dialog`. If it's a host-driven save dialog, ask the user. |
When you have to stop, the right call is roughly:
ask_user_question({
reason: "Browser flow requires you",
questions: [{ q: "I see a CAPTCHA on https://...; please solve it, then say 'continue'.", ... }]
})Tab discipline
Multi-tab work loses refs more than anything else. Two rules keep you sane:
1. **Name your tabs as soon as you open them.** Right after `tabs.new`, jot the `target_id` and the URL/role in your reasoning ("tab A11C = github, tab B22D = jira"). Always pass `target_id` explicitly to `tabs.select` instead of relying on "active". 2. **One snapshot per action burst per tab.** Don't snapshot tab A, switch to tab B for two ops, switch back to A, and reuse the old A refs. Re-snapshot when you come back.
Real Chrome tabs
Use the extension-backed tab lease protocol whenever the task depends on the user's real Chrome state:
status tabs.open_user_tabs tabs.claim target_id="<chrome-tab-id>" snapshot / act / observe tabs.finalize
Rules:
- `tabs.claim` takes temporary control of a real user tab. Release it with `tabs.release` o
🦭 会记忆、能持续推进目标、会动态编排多 Agent 的跨端桌面 AI 助手,也可服务化常驻 NAS / 云端 | A cross-device desktop AI agent with memory, autonomous goals, dynamic workflows, and headless deployment
Repo: shiwenwen/hope-agent
Other skills on hope-agent.
- /email-draft
Use when the user asks to draft, polish, translate, or reply to an email. Produces a clean draft with subject line, greeting, body, and sign-off, plus a pre-send self-check.
Open skill - /feishu
Use when the user mentions 飞书 / Feishu / Lark workspace operations: docx (云文档) read/write, bitable (多维表格) records / views / dashboards, drive (云盘) upload/download, wiki (知识库) link resolution, approval (审批) instance create/cancel/query, calendar (日历) event create/list/update +
Open skill - /ha-code-review
Hope-native review of uncommitted, staged, commit, branch, or PR changes: discover concrete regressions, independently verify candidates, and report actionable findings first without speculative noise.
Open skill - /ha-coding-common
Hope-native baseline for implementing, fixing, refactoring, and maintaining code: inspect the repository first, protect user changes, keep scope narrow, and finish with direct evidence.
Open skill - /ha-coding-plan
Hope-native implementation planning for non-trivial code changes: ground the plan in repository evidence, order dependencies, name critical files and risks, define verification, then continue execution when allowed.
Open skill - /ha-data-analytics
Hope-native local-first data analysis and Artifact reporting. Use for CSV/XLSX analysis, KPI readouts, metric diagnosis, product/business analysis, data-quality review, dashboards, charts, analytical reports, 数据分析, 指标诊断, 数据质量, 分析报告, or when the user wants a shareable offline
Open skill

